1.需求说明
react的渲染机制是父子组件同时渲染,不管子组件是否有变化只要父组件重新渲染了子组件就跟着重新渲染。为了避免不必要的消耗,我们可以使用memo钩子函数
2.使用memo前展示
import { memo,useState } from "react"
function Son(){
console.log("我是子组件");
return (
<div>我是子组件</div>
)
}
function Memo(){
const [text,setText] = useState('')
function kanno(){
setText('欢迎kanno')
}
return (
<div>
<button onClick={kanno}>我是父组件</button>
<div>{text}</div>
<Son/>
</div>
)
}
export default Memo
3.使用memo后展示
import { memo,useState } from "react"
const MemoSon = memo(function Son(){
console.log("我是子组件");
return (
<div>我是子组件</div>
)
})
function Memo(){
const [text,setText] = useState('')
function kanno(){
setText('欢迎kanno')
}
return (
<div>
<button onClick={kanno}>我是父组件</button>
<div>{text}</div>
<MemoSon/>
</div>
)
}
export default Memo
4.拓展补充
基本数据类型只要传递给子组件的值没有变化就不会触发子组件的重新渲染;
引用数据类型不管传递的值前后是否一样也会触发子组件的重新渲染,因为引用数据类型每次在父组件重新渲染时引用地址都发生了变化,也就导致子组件的重新渲染。可以使用useMemo钩子函数避免,但使用场景较小。
import { memo,useState } from "react"
const MemoSon = memo(function Son(){
console.log("我是子组件");
return (
<div>我是子组件</div>
)
})
function Memo(){
const [text,setText] = useState('')
// 基本数据类型
const [sonData,setSonData] = useState(666)
function kanno(){
setSonData(666); // 不会触发子组件的重新渲染
// setSonData('36除了6还是6'); // 会触发子组件的重新渲染
}
// 引用数据类型
const [sonContent,setSonContent] = useState([])
function shower(){
setSonContent([]); // 会触发子组件的重新渲染
}
return (
<div>
<button onClick={kanno}>我是父组件1</button>
<button onClick={shower}>我是父组件2</button>
<div>{text}</div>
<MemoSon data={sonData} content={sonContent}/>
</div>
)
}
export default Memo
5.如何避免引用数据没有变化还是渲染了子组件的问题
使用useMemo钩子函数:http://t.csdnimg.cn/l8Xjb
但是这样的写法使用场景较小>_<
import { memo,useState,useMemo } from "react"
const MemoSon = memo(function Son(){
console.log("我是子组件");
return (
<div>我是子组件</div>
)
})
function Memo(){
const [text,setText] = useState('')
// 基本数据类型
const [sonData,setSonData] = useState(666)
function kanno(){
setSonData(666); // 不会触发子组件的重新渲染
// setSonData('36除了6还是6'); // 会触发子组件的重新渲染
}
// 引用数据类型
const content = useMemo(()=>{
return []
},[])
const [sonContent,setSonContent] = useState(content)
function shower(){
setSonContent(content); // 会触发子组件的重新渲染
}
return (
<div>
<button onClick={kanno}>我是父组件1</button>
<button onClick={shower}>我是父组件2</button>
<div>{text}</div>
<MemoSon data={sonData} content={sonContent}/>
</div>
)
}
export default Memo