HOWTO · React

强制 React 组件重新渲染

更改 React 中无状态组件的默认行为。使用这些方法强制它们重新渲染

本页内容

默认情况下,React 组件会通过其 state 或 props 的更改触发重新渲染。大多数时候,如果你遵循 React 的最佳实践,这种行为足以达到预期的结果。

在某些情况下,框架的默认行为是不够的,你需要手动重新渲染组件。在执行此操作之前,请仔细查看代码。强制重新渲染仅在少数情况下是可行的选择。

强制 React 组件使用类组件重新渲染

如果使用得当,调用 React Class Component 的 setState() 方法应该总是触发重新渲染。shouldComponentUpdate() 生命周期可能包含阻止这种行为的条件逻辑。

如果你正在调用 setState() 但组件没有更新,则你的代码可能有问题。确保你有使用 forceUpdate() 方法的正当理由。

this.forceUpdate()

如果你的 render() 方法依赖于 state 或 props 之外的数据,并且你想根据该数据的更改触发重新渲染,你可以使用 forceUpdate() 方法。

示例代码:

class App extends Component {
  render() {
    return (    
    <div>
        <h1>{Math.random()}</h1>
        <button onClick={() => this.forceUpdate()}>Force Update</button>
    </div>)
  }
}

在这种情况下,更改 state 或 props 不会触发更新。执行此操作的是 forceUpdate() 方法。

最佳实践

React 开发人员应该只使用 forceUpdate() 作为最后的手段。渲染函数应该只读取 props 和 state。通过遵循这些指南,你可以确保 React 组件的简单性和效率。

不建议频繁使用 forceUpdate() 方法。如果你经常使用它,你可能需要查看你的代码,看看它是否可以改进。

强制 React 组件使用函数组件重新渲染

函数组件不包括 forceUpdate() 方法。但是,仍然可以使用 useState() 或 useReducer 钩子强制它们重新渲染。

useState

类似于类组件的 setState() 方法,只要更新后的 state 对象具有不同的值,useState() 钩子总是会触发更新。

你可以创建一个自定义钩子,使用 useState() 钩子来强制更新。这是这种可重用钩子的示例代码:

const useForceUpdate = () => {
  const [ignored, newState] = useState();
  return useCallback(() => newState({}), []);
}

众所周知,useState() 钩子返回两个值:state 的当前值及其设置器。在这种情况下,我们只需要 newState setter。

useReducer

由于 useState 钩子内部使用了 useReducer,你可以直接使用这个钩子来创建一个更优雅的解决方案。React 官方文档 推荐的解决方案也使用 useReducer()。这是一个示例解决方案:

const [any, forceUpdate] = useReducer(num => num + 1, 0);
function handleChange(){
    forceUpdate();
}

useReducer() 钩子返回当前的 state 和 dispatch 函数。在上面的例子中,我们使用 [variableName, dispatchName] 语法来存储这些值。

在此示例中,调用 handleChange() 处理程序将强制你的组件每次更新。

钩子不打算以这种方式使用。尝试将这些解决方案用于测试或异常情况。