我们都知道,当父组件的状态值(state)和属性值(props)发生改变后,子组件会随之重新渲染。
但是实际开发过程中,某些场景我们并不想让子组件重新渲染,以提高性能。一起看下面的例子:
import React, { useState, memo } from 'react';import { Button, Card, Alert } from 'antd';// 子组件const Child = () => {console.log("渲染了子组件");return (<Alert message='我是一个简单的子组件' />);}// 父组件const Parent = () => {const [count, setCount] = useState(0);// 按钮点击事件const handleClick = () => {setCount(count + 1);}return (<Card><p>{count}</p><p><Button onClick={handleClick}>点击+1</Button></p><Child /></Card>);}export default Parent;

我们的目的,仅仅是点击+1时,让数字增加1,即父组件渲染。但是很显然,每次父组件重新渲染后,子组件也随之渲染了。既然子组件没有任何改动,为什么还让它渲染呢?
出于优化考虑:
我们期待的结果是当子组件的state和props没有发生改变时,即使父组件重新渲染,也不要渲染子组件。
解决办法是,在子组件的最外层用React.memo,修改如下:
import React, { useState, memo } from 'react';import { Button, Card, Alert } from 'antd';// 子组件:用React.memo包裹const Child = memo(() => {console.log("渲染了子组件");return (<Alert message='我是一个简单的子组件' />);})// 父组件const Parent = () => {const [count, setCount] = useState(0);// 按钮点击事件const handleClick = () => {setCount(count + 1);}return (<Card><p>{count}</p><p><Button onClick={handleClick}>点击+1</Button></p><Child /></Card>);}export default Parent;

当我们再次点击+1时,控制台并没有打印出:”渲染了子组件”,表明子组件并没有渲染。
思考:
import React, { useState, memo } from 'react';import { Button, Card, Alert } from 'antd';// 子组件const Child = memo(({ textInfo }) => {console.log("渲染了子组件");return (<Alert message='我是一个简单的子组件' />);})// 父组件const Parent = () => {const [count, setCount] = useState(0);const [text, setText] = useState("你好,世界!");// 按钮点击事件const handleClick = () => {setCount(count + 1);}return (<Card><p>{count}</p><p><Button onClick={handleClick}>点击+1</Button></p><Child textInfo={{ text }} /></Card>);}export default Parent;
我们增加一个变量 text ,当我们点击+1,发现子组件在控制台还是打印出:”渲染了子组件”。有的小伙伴可能该问了,text 的值一直是:”你好,世界!”,props并没有发生改变,子组件为啥还是会重新渲染呢?难道是React.memo失效了?
如果我把
<Child textInfo={{ text }} />
更改为:
<Child textInfo={ text } />
结果是不是会一样呢?
如果不懂怎么解决上述问题,嘿嘿。那就老实和我一起继续往下学习吧:React Hook — useMemo
