首先看一下原始代码:
我们写了三个组件,跟组件,和组件A、组件B;
他们的嵌套关系是跟组件中两个兄弟组件A和B;
import './App.css';
import React from 'react'
function App() {
let [nameA, setNameA] = React.useState('zjqA')
let [nameB, setNameB] = React.useState('zjqB')
const changeNameFunA = () => {
setNameA("AAAA")
}
const changeNameFunB = () => {
setNameB("BBBB")
}
return (
<div>
<A name={nameA} />
<B name={nameB} />
<button onClick={changeNameFunA}>点击改变nameA</button>
<button onClick={changeNameFunB}>点击改变nameB</button>
</div>
);
}
const A = ({ name }) => {
console.log("A组件重新渲染")
return (
<>
<h1>我是A组件:{name}</h1>
</>
)
}
const B = ({ name }) => {
console.log("B组件重新渲染")
return (
<>
<h1>我是B组件:{name}</h1>
</>
)
}
export default App;
页面样式:
页面首次加载的时候渲染组件A和组件B的时候会执行A和B组件中的打印语句:
当我们点击第一个按钮"点击改变nameA",我们会发现控制台同时执行了A、B组件中的打印。因为父组件渲染,导致所有子组件都随之重新渲染。
这个其实我们在类组件中可以很好的解决:
1.shouldComponentUpdate这个钩子做判断返回true或者false
2.ComponentPure 使用纯组件
在hooks中我们使用useMemo:
useMemo用法:
import './App.css';
import React from 'react'
function App() {
let [nameA, setNameA] = React.useState('zjqA')
let [nameB, setNameB] = React.useState('zjqB')
const changeNameFunA = () => {
setNameA("AAAA")
}
const changeNameFunB = () => {
setNameB("BBBB")
}
const comA = React.useMemo(() => <A name={nameA} />, [nameA])
const comB = React.useMemo(() => <B name={nameB} />, [nameB])
return (
<div>
{comA}
{comB}
<button onClick={changeNameFunA}>点击改变nameA</button>
<button onClick={changeNameFunB}>点击改变nameB</button>
</div>
);
}
const A = ({ name }) => {
console.log("A组件重新渲染")
return (
<>
<h1>我是A组件:{name}</h1>
</>
)
}
const B = ({ name }) => {
console.log("B组件重新渲染")
return (
<>
<h1>我是B组件:{name}</h1>
</>
)
}
export default App;
useMemo不仅仅可以用来优化子组件渲染,
const memoizedValue = useMemo(() => computeExpensiveValue(a, b), [a, b]);
返回一个memoized值。 传递“创建”函数和依赖项数组。useMemo只会在其中一个依赖项发生更改时重新计算memoized值。此优化有助于避免在每个渲染上进行昂贵的计算。
可以堪称一个依赖项,a,b发生改变memoizedValue 才被重新赋值,有种缓存的感觉。
例子:
import './App.css';
import React from 'react'
function App() {
let [name, setName] = React.useState('zjq')
const changeNameFunA = () => {
setName("AAAA")
}
const XHnameMemo = React.useMemo(()=>name+'小红',[name])
return (
<div>
<h1>我的名字是:{name}</h1>
<button onClick={changeNameFunA}>点击改变name</button>
<h1>小红的名字是:{XHnameMemo}</h1>
</div>
);
}
export default App;
点击按钮的时候name、XHnameMemo都被重新赋值,原因是XHnameMemo依赖于name的值,所有有一种监听且依赖的效果,一旦name值发生改变XHnameMemo 会被重新赋值。