新闻中心

hooks写React组件要注意哪些细节

今天小编给大家分享一下hooks写React组件要注意哪些细节的注节相关知识点,内容详细,意细逻辑清晰,注节相信大部分人都还太了解这方面的意细知识,所以分享这篇文章给大家参考一下,注节希望大家阅读完这篇文章后有所收获,意细下面我们一起来了解一下吧。注节

01.不需要render的意细场景下使用useState

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

不推荐×

function ClickButton(props){   const [count,意细 setCount] = useState(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都会使组件重新渲染一次,而这个渲染并不是我们需要的,多出来的渲染会使得页面的性能变差,因此我们可以改造一下代码,如下代码:

推荐&radic;如果我们只是单纯的想要一个能在组件声明周期内保存的变量,但是变量的更新不需要组件的重新渲染,我们可以使用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来处理路由的跳转,我们很经常在组件中写了一个按钮,通过点击按钮的事件来处理路由的跳转,如下代码:

不推荐&times;

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

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

推荐&radic;

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

03.通过useEffect来处理actions

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

不推荐&times;

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的成功请求数据。因此我们可以改造一下代码,如下代码:

推荐&radic;

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.单一职责组件

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

不推荐&times;

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

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

推荐&radic;

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

function Header(props) {   return (    &lt;header&gt;      { isMobile() ? &lt;BurgerButton menuItems={ menuItems} /&gt; : &lt;Tabs tabData={ menuItems} /&gt;}    &lt;/header&gt;  )}

05.单一职责useEffects

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

不推荐&times;

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同时触发了两个副作用,但是并不都是我们需要的副作用,因此我们可以改造一下代码,如下代码:

推荐&radic;将两个副作用从一个useEffect中分离出来。

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

以上就是“hooks写React组件要注意哪些细节”这篇文章的所有内容,感谢各位的阅读!相信大家阅读完这篇文章都有很大的收获,小编每天都会为大家更新不同的知识,如果还想学习更多的知识,请关注本站行业资讯频道。

上一篇:彭十六 樱花 美女高清电脑壁纸 下一篇:中华H220 H230专用中控仪表台避光垫汽车装饰改装配件防晒遮光垫

Copyright © 2023 imtoken钱包安卓版下载 版权所有   网站地图