重渲染
组件自身状态变更
组件自身通过 setState 更新状态,会导致组件 re-render。
const Child = () => {
const [count, setCount] = useState(0)
console.log('re-render!!')
return (
<div>
<div>{`count: ${count}`}</div>
<button onClick={() => setCount(count + 1)}>Click</button>
</div>
)
}
// 输出
re-render!!
父组件状态变更
父组件通过 setState 更新状态,会导致父组件自身及其子组件 re-render,无论子组件是否有通过 Props 接收父组件状态。
const Parent = () => {
const [count, setCount] = useState(0)
console.log('Parent re-render!!')
return (
<div>
<div>{`count: ${count}`}</div>
<button onClick={() => setCount(count + 1)}>Click</button>
<Child/>
</div>
)
}
const Child = () => {
console.log('Child re-render!!')
return <div>Violet Evergadern</div>
}
// 输出
Parent re-render!!
Child re-render!!
TIP
Props 发生变化与组件 re-render 没有任何关系,本质还是父组件状态变更导致的。
Context 值变更
Context 值变更,会导致用到 Context 值的组件 re-render,且根据上一条规则,该组件子组件也会 re-render。 至于 Context Provider 所在组件及用到 Context 值的组件中间跳过的组件,则不会进行 re-render。
const context = createContext()
const App = () => {
return (
<Parent>
<Child/>
</Parent>
)
}
const Parent = ({children}) => {
const [count, setCount] = useState(0)
console.log('Parent re-render!!')
return (
<div>
<div>{`count: ${count}`}</div>
<button onClick={() => setCount(count + 1)}>Click</button>
<Context.Provider value={count}>
{children}
</Context.Provider>
</div>
)
}
const Child = () => {
console.log('Child re-render!!')
return <GrandChild/>
}
const GrandChild = () => {
const count = useContext(context)
console.log('GrandChild re-render!!')
return <GrandGrandChild/>
}
const GrandGrandChild = () => {
console.log('GrandGrandChild re-render!!')
return <div>Violet Evergadern</div>
}
// 输出
Parent re-render!!
GrandChild re-render!!
GrandGrandChild re-render!!
TIP
其实 Context 值之所以会变更,本质还是 State 变化了,所以可以说 React 中一切 re-render 重渲染都跟 State 状态有关。