重渲染

组件自身状态变更

组件自身通过 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 状态有关。

参考

Last Updated:
Contributors: Vsnoy