【问题标题】:forceUpdate with React hooks使用 React 钩子强制更新
【发布时间】:2020-01-12 23:30:59
【问题描述】:

是否有可以与 React 钩子一起使用的 forceUpdate 替代品?

我的用例是组件实例之间的共享状态。本质上,每个实例只是对单个全局状态的视图。使用 ES6 类,代码在 componentDidMount 中注册/注销具有状态的组件,状态在其更改时调用 forceUpdate,然后 render 方法直接查询全局状态。

我考虑将其切换为挂钩。最初 useEffect 似乎是该问题的完美匹配。但后来我意识到我无法访问 forceUpdate。

我考虑过一种解决方法,它调用 useState 钩子来添加一个虚拟计数器,然后从效果钩子中更新计数器,但感觉就像一个 hack。我还可以将所有相关的共享状态参数复制到效果挂钩中的组件状态中,然后从状态中引用这些参数。但它本质上复制了状态,因为当前我可以直接在渲染方法中直接使用这些行,而使用复制状态的行来膨胀代码并没有好处。

更新:这里是 codesandbox.io 链接,其中包含共享状态示例,该示例使用了我想在不复制状态或使用虚假状态更新的情况下将其转换为挂钩的类组件。

【问题讨论】:

  • 如果您在codesandbox.io 中重现问题,这将非常有帮助
  • 组件在状态 或 道具更新时重新渲染...您是否尝试过传递“数据”道具以“强制”重新渲染(类似于 react-virtualize 的工作方式)?
  • 渲染函数中使用的值是组件内部的。将它们作为属性传递意味着父级需要了解此实现细节,并且本质上在所有实例中复制单个外部状态,从而使实现复杂化而没有任何好处。

标签: reactjs react-hooks


【解决方案1】:

您可以使用另一种技巧来执行 forceUpdate。这里是:

来自反应文档:

如果下一个值与前一个值相同,useState 和 useReducer Hooks 都会退出更新。就地改变状态并调用 setState 不会导致重新渲染。 通常,你不应该在 React 中改变本地状态。但是,作为逃生舱口,即使状态没有改变,您也可以使用递增计数器强制重新渲染。

【讨论】:

  • 谢谢,我错过了。因此,添加任意突变计数器是 React 建议的解决方案。我想我会留在课堂上。
  • 代码长度方面我更喜欢钩子。很容易实现。
【解决方案2】:

你可以这样做

您可以简单地添加一个可以更改的虚拟状态以可靠地启动重新渲染。

const [rerender, setRerender] = useState(false);

...
setRerender(!rerender); //whenever you want to re-render

这将确保组件的重新渲染,因为组件总是在状态更改时重新渲染

【讨论】:

    【解决方案3】:

    作为一种解决方法,我最终得到了以下功能组件的钩子:

    function useForceUpdate() {
      const [forcedUpdateCounter, setState] = useState(0);
      return () => setState(forcedUpdateCounter + 1);
    }
    

    并像这样使用它:

    function ExampleWithSharedState(props) {
      const forceUpdate = useForceUpdate();
      useEffect(() => {
        SharedState.addObserver(forceUpdate);
        return () => {
          SharedState.removeObserver(forceUpdate);
        };
      });
      return <div>Hello, {SharedState.getValue()}</div>
    }
    

    【讨论】:

      猜你喜欢
      • 2020-06-01
      • 2019-04-12
      • 2019-09-07
      • 2019-10-29
      • 1970-01-01
      • 1970-01-01
      • 2021-05-23
      • 2020-11-02
      • 1970-01-01
      相关资源
      最近更新 更多