首页前端开发JavaScript使用hooks写React组件需要注意的5个地方

使用hooks写React组件需要注意的5个地方

时间2024-02-01 07:44:02发布访客分类JavaScript浏览423
导读:收集整理的这篇文章主要介绍了使用hooks写React组件需要注意的5个地方,觉得挺不错的,现在分享给大家,也给大家做个参考。 目录01.不需要render的场景下使用useState0...
收集整理的这篇文章主要介绍了使用hooks写React组件需要注意的5个地方,觉得挺不错的,现在分享给大家,也给大家做个参考。
目录
  • 01.不需要render的场景下使用useState
  • 02.使用了router.push而非link
  • 03.通过useEffect来处理actions
  • 04.单一职责组件
  • 05.单一职责useEffects
  • 参考:

Hook是React16.8开始新增的特性。虽然React官方文档已经作出了针对react hooks的相关概念的讲解,但是光看官方文档是很难将hooks使用好的,在编写hooks的过程中很容易跳进陷阱和错误。本文总结了5个不好的地方。

01.不需要render的场景下使用usestate

在函数组件中我们可以使用useState来管理状态,这使得对状态的管理变得很简单,但是也容易被滥用,我们通过下面的代码样例看下容易忽略的地方。

不推荐×

function ClickButton(PRops){
     const [count, setCount] = setState(0) const onClickCount = () =>
 {
      setCount((c) =>
 c + 1) }
     const onClickRequest = () =>
 {
  apicall(count) }
      return (  div>
   button onClick={
onClickCount}
    >
    Click/button>
   button onClick={
onClickRequest}
    >
    SubmIT/button>
      /div>
 )}
    

问题所在:仔细看上面的代码,乍一看其实也没什么问题,点击按钮更新 count。但是问题也就出在这里,我们的 return 部分并没有用到 count 状态,而每次 setCount 都会使组件重新渲染一次,而这个渲染并不是我们需要的,多出来的渲染会使得页面的性能变差,因此我们可以改造一下代码,如下代码:

推荐√
如果我们只是单纯的想要一个能在组件声明周期内保存的变量,但是变量的更新不需要组件的重新渲染,我们可以使用 useRef 钩子。

function ClickButton(props){
     const count = useRef(0) const onClickCount = () =>
 {
  count.current++ }
     const onClickRequest = () =>
 {
  apiCall(count.current) }
     return (  div>
   button onClick={
onClickCount}
    >
    Click/button>
   button onClick={
onClickRequest}
    >
    Submit/button>
      /div>
 )}
    

02.使用了router.push而非link

在React SPA应用中,我们用react-router来处理路由的跳转,我们很经常在组件中写了一个按钮,通过点击按钮的事件来处理路由的跳转,如下代码:

不推荐×

function ClickButton(props){
     const history = useHistory() const onClickGo = () =>
 {
  history.push('/where-page') }
 return button onClick={
onClickGo}
    >
    Go to where/button>
}
    

问题所在:尽管上述代码可以正常工作,但是却不符合Accessibility(易访问性设计)的要求,此类按钮并不会被屏幕阅读器当作一个可以跳转的链接。因此我们可以改造一下代码,如下代码:

推荐√

function ClickButton(props){
     return Link to="/next-page">
      span>
    Go to where/span>
     /Link>
}
    

03.通过useEffect来处理actions

有时候,我们只想在 React 更新 DOM 之后运行一些额外的代码。比如发送网络请求,手动变更 DOM,记录日志。

不推荐×

function DataList({
 onSuccess }
) {
     const [loading, setLoading] = useState(false);
     const [error, setError] = useState(null);
     const [data, setData] = useState(null);
     const fetchData = () =>
 {
      setLoading(true);
      callApi()   .then((res) =>
     setData(res))   .catch((err) =>
     setError(err))   .finally(() =>
     setLoading(false));
 }
    ;
     useEffect(() =>
 {
      fetchData();
 }
    , []);
     useEffect(() =>
 {
      if (!loading &
    &
     !error &
    &
 data) {
       onSuccess();
  }
 }
    , [loading, error, data, onSuccess]);
     return div>
Data: {
data}
    /div>
    ;
}
    

问题所在:上面的代码使用了两个useEffect ,第一个用来请求异步数据,第二个用来调用回调函数。在第一个异步请求数据成功,才会触发第二个 useEffect 的执行,但是,我们并不能完全保证,第二个 useEffect 的依赖项完全受控于第一个 useEffect 的成功请求数据。因此我们可以改造一下代码,如下代码:

推荐√

function DataList({
 onSuccess }
) {
     const [loading, setLoading] = useState(false);
     const [error, setError] = useState(null);
     const [data, setData] = useState(null);
     const fetchData = () =>
 {
      setLoading(true);
      callApi()   .then((res) =>
 {
    setData(res)    onSuccess()    }
    )   .catch((err) =>
     setError(err))   .finally(() =>
     setLoading(false));
 }
    ;
     useEffect(() =>
 {
      fetchData();
 }
    , []);
     return div>
Data: {
data}
    /div>
    ;
}
    

04.单一职责组件

什么时候该把一个组件分成几个更小的组件?如何构建组件树?在使用基于组件的框架时,所有这些问题每天都会出现。然而,设计组件时的一个常见错误是将两个用例组合成一个组件。

不推荐×

function Header({
 menuItems }
) {
     return (  header>
   HeaderInner menuItems={
menuItems}
     />
      /header>
     );
}
function HeaderInner({
 menuItems }
) {
 return ismobile() ? BurgerButton menuItems={
menuItems}
     />
 : Tabs tabData={
menuItems}
     />
    ;
}
    

问题所在:上面的代码通过这种方法,组件HeaderInner试图同时成为两个不同的东西,一次做不止一件事情并不是很理想。此外,它还使得在其他地方测试或重用组件变得更加困难。因此我们可以改造一下代码,如下代码:

推荐√

将条件提升一级,可以更容易地看到组件的用途,并且它们只有一个职责,即Tabs/> BurgerButton/> ,而不是试图同时成为两个不同的东西。

function Header(props) {
     return (  header>
   {
isMobile() ? BurgerButton menuItems={
menuItems}
     />
 : Tabs tabData={
menuItems}
     />
}
      /header>
 )}
    

05.单一职责useEffects

通过对比componentWillReceivePropscomponentDidUpdate方法,才认识到userEffect的美丽。但是没有妥当使用useEffect也是容易出问题的。

不推荐×

function Example(props) {
     const location = useLocation();
     const fetchData = () =>
 {
  /* Calling the api */ }
    ;
     const updatebreadcrumbs = () =>
 {
  /* Updating the breadcrumbs*/ }
    ;
     useEffect(() =>
 {
      fetchData();
      updateBreadcrumbs();
 }
    , [location.pathname]);
     return (  div>
       BreadCrumbs />
      /div>
     );
}
    

问题所在:上面的useEffect同时触发了两个副作用,但是并不都是我们需要的副作用,因此我们可以改造一下代码,如下代码:

推荐√

将两个副作用从一个useEffect中分离出来。

function Example(props) {
     const location = useLocation();
     const fetchData = () =>
 {
  /* Calling the api */ }
    ;
     const updateBreadcrumbs = () =>
 {
  /* Updating the breadcrumbs*/ }
    ;
     useEffect(() =>
 {
      fetchData();
      updateBreadcrumbs();
 }
    , [location.pathname]);
     return (  div>
       BreadCrumbs />
      /div>
     );
}
    

参考:

Five common mistakes writing react components (with hooks) in 2020

以上就是使用hookS写React组件需要注意的5个地方的详细内容,更多关于hooks写React组件的资料请关注其它相关文章!

您可能感兴趣的文章:
  • React hooks的优缺点详解
  • React Hooks常用场景的使用(小结)
  • react hooks入门详细教程
  • 基于react hooks,zarm组件库配置开发h5表单页面的实例代码
  • React 使用Hooks简化受控组件的状态绑定
  • 30分钟精通React今年最劲爆的新特性——React Hooks
  • 记录一次完整的react hooks实践
  • React Hooks的深入理解与使用
  • 详解React Hooks是如何工作的

声明:本文内容由网友自发贡献,本站不承担相应法律责任。对本内容有异议或投诉,请联系2913721942#qq.com核实处理,我们将尽快回复您,谢谢合作!

React

若转载请注明出处: 使用hooks写React组件需要注意的5个地方
本文地址: https://pptw.com/jishu/595116.html
ASP.NET页面优化 性能提升8倍的方法 asp.net运行提示未将对象引用设置到对象的实例错误解决方法

游客 回复需填写必要信息