reactjs - 如何强制 React(使用钩子(Hook)的功能组件)在 props 更改时从头开始创建新组件?

标签 reactjs react-hooks

TLDR

有没有办法强制 React 从头开始​​重新创建组件(使用钩子(Hook)的功能组件),而不是在 prop 上重新渲染它改变?

编辑

关键属性确实有效。我遇到的问题是由于我正在执行的状态更新顺序造成的。第一次更新是立即尝试渲染需要上次更新已完成的组件。

<小时/>

我正在开发一个名为 <AddProductWidget> 的组件,将得到以下 props关于产品并需要显示其详细信息。它属于一个带有搜索栏的页面,您填写productID,它会从云功能获取产品详细信息。

它的渲染如下:

  <AddProductWidget
    userImages={props.productDetails.userImages}    // Array of strings (urls)
    title={props.productDetails.title}
    stars={props.productDetails.stars}
  />

AddProductWidget.js

它呈现 <UserImages>允许用户在保存到数据库之前单击一些图像进行选择的组件。所以它需要一个state “记住”用户点击了哪些图像。

function AddProductWidget(props) {

  const [userImagesSelected, setUserImagesSelected] = useState(
    () => {
      if (props.userImages && props.userImages > 0) {
        return new Array(props.userImages.length).fill(false);
      }
      return null;
    }
  );

  // IT renders the <UserImages> component
  // The code here is simplified

  return(
      <UserImages
        userImages={props.userImages}
        userImagesSelected={userImagesSelected}
        setUserImagesSelected={setUserImagesSelected}
      />
  );

}

该数组的初始状态 userImagesSelected应该与 userImages 的长度相同数组并填充 false值,将变为 true一旦用户开始点击图像。如果产品没有用户图片,props.userImages将是nulluserImagesSelected也应该是null .

当我加载第一个产品时,一切都按预期工作。无论是否有图像,一切都正确显示。

问题:

问题是,例如,当我加载一个包含 0 个图像的产品,然后加载另一个包含 5 个图像的产品时。基本上是props对于 AddProductWidget会改变(因为它收到了新产品),但是因为 React 似乎试图使用相同的组件实例,所以我收到一个错误,因为我的 UserImages组件会尝试渲染选中的图像信息,但是userImagesSelected的状态仍将是null ,因为最后的产品没有图片。

当我使用类时,我可以强制 React 使用 key 重新创建组件实例。属性,但这似乎不适用于钩子(Hook),因为以下代码没有解决我的问题:

  <AddProductWidget
    key={productID}
    userImages={props.productDetails.userImages}    // Array of strings (urls)
    title={props.productDetails.title}
    stars={props.productDetails.stars}
  />

问题

有没有办法强制 React 从头开始​​重新创建组件(使用钩子(Hook)的功能组件),而不是在 prop 上重新渲染它改变?

额外

A 找到了一种解决方法,但看起来有点 hacky,即使它在 React 文档中。它基本上使用状态来检测 props 何时更改并调用setState()在渲染期间。我希望更好地从头开始重新创建我的组件。

Hooks FAQ: How do I implement getDerivedStateFromProps

最佳答案

不确定您如何决定不同的 key 不会重新安装组件,但它应该这样做(您确定 key 已更改吗?)

这是一个显示此内容的运行示例

function Test() {
  React.useEffect(() => {
    console.log('Test was mounted');
    return () => {
      console.log('Test was un-mounted');
    };
  }, []);

  return "hi there, I'm Test";
}

function App() {
  const [val, setVal] = React.useState("Change me...");
  return (
    <div className="App">
      <input value={val} onChange={e => setVal(e.target.value)} />
      <br />
      <Test key={val} />
    </div>
  );
}

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
<script crossorigin src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
<div id="root" />

关于reactjs - 如何强制 React(使用钩子(Hook)的功能组件)在 props 更改时从头开始创建新组件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55383320/

相关文章:

javascript - 如何将 react 钩子(Hook)内的所有状态变量传递给我的子组件

javascript - 将基本轮询变为长轮询

javascript - 在 React.js 中,如何使用 React-bootstrap 创建链接来更改事件选项卡?

javascript - 导入 redux 表单后未拾取操作

javascript - 使用 React-redux 中的 connect 时返回未定义的方法

reactjs - 为什么使用上下文 API 在获取中设置数据状态会陷入无限获取循环?

reactjs - 如何访问缓存以使用 React Query 显示数据?

javascript - _this3.state.method 不是函数

reactjs - 仅当输入中的所有元素发生变化时,如何使 useEffect Hook 调用提供的效果?

javascript - 如何避免在 native react 中首次渲染或如何仅渲染获取数据避免一次未定义?