Using hooks to write react components

Forrest sauce 2021-04-07 21:41:20
using hooks write react components


 Screenshot of Sogou 20210405114309.png Hook yes React16.8 Start adding features . although React The official document has made a statement about React hooks Explain the related concepts of , But it's hard to translate... Just by looking at official documents hooks Use good , Writing hooks It's easy to jump into pitfalls and mistakes in the process . This article summarizes 5 It's a bad place .

01. Unwanted render Used in the scene of useState

In function components we can use useState To manage status , This makes it easy to manage States , But it's also easy to abuse , Let's take a look at the following code examples to see what's easy to ignore .

Not recommended ×

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>
)
}
 Copy code 

The problem : Look carefully at the code above , At first glance, it doesn't matter , Click the button to update count. But that's the problem , our return Part of it doesn't use count state , And every time setCount Will cause the component to render again , And this rendering is not what we need , The extra rendering will make the performance of the page worse , So we can transform the code , The following code :

recommend √
If we just want a variable that can be saved in the component declaration cycle , However, the update of variables does not require re rendering of components , We can use useRef hook .

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>
)
}
 Copy code 

02. Used router.push Instead of link

stay React SPA Application , We use it react-router To handle route hops , We often write a button in a component , Handle the route jump by clicking the button event , The following code :

Not recommended ×

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

The problem : Although the above code works , But it doesn't fit Accessibility( Accessibility design ) The requirements of , This kind of button is not used by screen readers as a link to jump . So we can transform the code , The following code :

recommend √

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

03. adopt useEffect To deal with it actions

occasionally , We just want to be React to update DOM Then run some extra code . Such as sending network requests , Manual change DOM, Log .

Not recommended ×

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>;
}
 Copy code 

The problem : The above code uses two useEffect , The first one is used to request asynchronous data , The second is used to call the callback function . In the first asynchronous request data success , To trigger the second useEffect Implementation , however , We can't guarantee that , the second useEffect Is completely controlled by the first useEffect Successful request data for . So we can transform the code , The following code :

recommend √

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>;
}
 Copy code 

04. Single responsibility component

When to divide a component into several smaller components ? How to build a component tree ? When using a component-based framework , All of these problems come up every day . However , A common mistake in designing components is to combine two use cases into one component .

Not recommended ×

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

The problem : The code above works in this way , Components HeaderInner Trying to be two different things at the same time , It's not ideal to do more than one thing at a time . Besides , It also makes it more difficult to test or reuse components elsewhere . So we can transform the code , The following code :

recommend √

Raise the conditions one level , It's easier to see what components are for , And they have only one responsibility , namely <Tabs/> or <BurgerButton/>, Instead of trying to be two different things at the same time .

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

05. Single responsibility useEffects

by force of contrast componentWillReceiveProps or componentDidUpdate Method , Just realized that userEffect The beauty of . But it's not used properly useEffect It's also easy to have problems .

Not recommended ×

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>
);
}
 Copy code 

The problem : above useEffect Two side effects are triggered at the same time , But it's not all the side effects we need , So we can transform the code , The following code :

recommend √
Take the two side effects from one useEffect Separate from .

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>
);
}
 Copy code 

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

版权声明
本文为[Forrest sauce]所创,转载请带上原文链接,感谢
https://qdmana.com/2021/04/20210407213622954T.html

  1. Behind the miracle of the sixth championship is the football with AI blessing in the Bundesliga
  2. An easy to use Visual Studio code extension - live server, suitable for front-end gadget development
  3. 用 Python 抓取公号文章保存成 HTML
  4. User login of front end spa project based on Vue and Quasar (2)
  5. Summary of common selectors in CSS
  6. Using Python to grab articles with public number and save them as HTML
  7. To "restless" you
  8. 【免费开源】基于Vue和Quasar的crudapi前端SPA项目实战—环境搭建 (一)
  9. 【微信小程序】引入阿里巴巴图标库iconfont
  10. layui表格点击排序按钮后,表格绑定事件失效解决方法
  11. Unity解析和显示/播放GIF图片,支持http url,支持本地file://,支持暂停、继续播放
  12. 【vue】 export、export default、import的用法和区别
  13. [free and open source] crudapi front end spa project based on Vue and Quasar
  14. [wechat applet] introduces Alibaba icon library iconfont
  15. Layui table click Sort button, table binding event failure solution
  16. Element树形控件Tree踩坑:修改current-node-key无效
  17. Unity parses and displays / plays GIF images, supports HTTP URL, supports local file: / /, supports pause and resume playback
  18. Element树形控件Tree踩坑:修改current-node-key无效
  19. The usage and difference of export, export default and import
  20. Element tree control: invalid to modify current node key
  21. Element tree control: invalid to modify current node key
  22. linux下安装apache(httpd-2.4.3版本)各种坑
  23. How to install Apache (httpd-2.4.3) under Linux
  24. 程序员业余时间写的代码也算公司的?Nginx之父被捕引发争议
  25. Nacos serialize for class [com.alibaba.nacos.common.http.HttpRestResult] failed.
  26. Do programmers write code in their spare time? Controversy over the arrest of nginx's father
  27. Nacos serialize for class [ com.alibaba.nacos . common.http.HttpRestResult ] failed.
  28. Seamless management of API documents using eolink and gitlab
  29. vue 的基础应用(上)
  30. 28岁开始零基础学前端,这些血的教训你一定要避免
  31. Basic application of Vue
  32. Starting at the age of 28, you must avoid these bloody lessons
  33. Ubuntu 16.04 can not connect to the wireless solution and QQ installation
  34. Industry security experts talk about the rapid development of digital economy, how to guarantee the security of data elements?
  35. 利用Vue实现一个简单的购物车功能
  36. Behind the "tireless classroom" and teacher training, can byte education really "work wonders"?
  37. Using Vue to realize a simple shopping cart function
  38. 【css】伪类和伪类元素的区别
  39. 【css效果】实现简单的下拉菜单
  40. 【vue】父子组件传值
  41. The difference between pseudo class and pseudo class elements
  42. [CSS effect] simple drop-down menu
  43. [Vue] value transfer by parent-child component
  44. 【css】设置table表格边框样式
  45. 【css】修改input,textarea中的placeholder样式
  46. vue-router的两种模式(hash和history)及区别
  47. CSS3的滤镜filter属性
  48. [CSS] set table border style
  49. [CSS] modify the placeholder style in input and textarea
  50. Two modes of Vue router (hash and History) and their differences
  51. Filter property of CSS3
  52. 全局安装gulp 报错问题解决
  53. Solution of error report in global installation of gulp
  54. 18个好用的自定义react hook
  55. 你应该知道的常用服务器HTTP状态码?
  56. 18 user defined react hooks
  57. What HTTP status codes should you know about common servers?
  58. 手把手教你打造属于自己团队的前端小报系统
  59. Hand in hand to teach you to build your own front-end tabloid system
  60. In 2021, enterprise SEO actual operation, how to less update, batch ranking regional words?