时间:2021-05-25
Hook是React16.8开始新增的特性。虽然React官方文档已经作出了针对React hooks的相关概念的讲解,但是光看官方文档是很难将hooks使用好的,在编写hooks的过程中很容易跳进陷阱和错误。本文总结了5个不好的地方。
在函数组件中我们可以使用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 钩子。
在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>}有时候,我们只想在 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>;}什么时候该把一个组件分成几个更小的组件?如何构建组件树?在使用基于组件的框架时,所有这些问题每天都会出现。然而,设计组件时的一个常见错误是将两个用例组合成一个组件。
不推荐×
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> )}通过对比componentWillReceiveProps或componentDidUpdate方法,才认识到userEffect的美丽。但是没有妥当使用useEffect也是容易出问题的。
不推荐×
function Example(props) { const location = useLocation(); const fetchData = () => { }; const updateBreadcrumbs = () => { }; useEffect(() => { fetchData(); updateBreadcrumbs(); }, [location.pathname]); return ( <div> <BreadCrumbs /> </div> );}问题所在:上面的useEffect同时触发了两个副作用,但是并不都是我们需要的副作用,因此我们可以改造一下代码,如下代码:
推荐√
将两个副作用从一个useEffect中分离出来。
function Example(props) { const location = useLocation(); const fetchData = () => { }; const updateBreadcrumbs = () => { }; useEffect(() => { fetchData(); updateBreadcrumbs(); }, [location.pathname]); return ( <div> <BreadCrumbs /> </div> );}Five common mistakes writing react components (with hooks) in 2020
以上就是使用hooks写React组件需要注意的5个地方的详细内容,更多关于hooks写React组件的资料请关注其它相关文章!
声明:本页内容来源网络,仅供用户参考;我单位不保证亦不表示资料全面及准确无误,也不保证亦不表示这些资料为最新信息,如因任何原因,本网内容或者用户因倚赖本网内容造成任何损失或损害,我单位将不会负任何法律责任。如涉及版权问题,请提交至online#300.cn邮箱联系删除。
在上一节中,我们讲到了React组件,说了如何使用ES6类创建一个React组件并在其他的地方使用它。这一节我们将讲到React组件的两大灵魂——props和s
相信有过React使用经验的人对ref都会熟悉,它可以用来获取组件实例对象或者是DOM对象。而useRef这个hooks函数,除了传统的用法之外,它还可以“跨渲
当我刚开始写React的时候,我看过很多写组件的方法。一百篇教程就有一百种写法。虽然React本身已经成熟了,但是如何使用它似乎还没有一个“正确”的方法。所以我
开门见山了,大家需要注意的地方:HTML5不再支持使用frame,iframe只有src属性一、使用iframe的优缺点优点: 1.程序调入静态页面比较方便;
点击进入Lombok官网下载Lombokjar包使用Lombok可能需要注意的地方(1)、当你的IDE是Idea时,要注意你的Idea是支持Lombok的,如果