使用 useState 钩子更改道具时组件不会重新渲染

新手上路,请多包涵

每次我在数据道具中获得新数据但组件不会重新渲染,直到我调用 handlePanelSelection()

 function StepPanel({ data, getTranslations }) {
  const [panelsData, changePanel] = useState(data);

  function handlePanelSelection(panelId) {
    switch (panelId) {
      case 8:
        changePanel(getTranslations.NeeSubCategory);
        break;
      default:
        changePanel(data);
        break;
    }
  }
  return (
    <>
      {panelsData.map(details => {
        const imgsrc = requireContext('./' + details.image);
        return (
          <div key={details.id} className="block-list">
            <div className="left-block">
              <img src={imgsrc} alt="" />
            </div>
            <div className="right-block">
              <h3>{details.title}</h3>
              <p>{details.description}</p>
              <label htmlFor="radio1" className="radio-btn">
                <input
                  type="radio"
                  onClick={() => handlePanelSelection(details.id)}
                  name="radio1"
                />
                <span></span>
              </label>
            </div>
          </div>
        );
      })}
    </>
  );
}

但是当我像下面这样移除钩子时它可以工作

function StepPanel({ data, getTranslations }) {

  return (
    <>
      {data.map(details => { ... })}
    </>
  )
}

我想实现一个功能,当我在数据道具中获取新数据时,组件会重新渲染,但当我需要在内部重新渲染时,例如我更改 panelId = 8 ,然后它也会重新渲染,这种方法可以吗?

上面的代码似乎每次都重新渲染,但每次都使用相同的数据,即它不会每次都更新 panelData 尽管每次数据道具都提供了新的更新值

控制台图像

原文由 Adarsh 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 707
2 个回答

这是因为当你这样做时:

 const [panelsData, changePanel] = useState(data);

您仅使用 data 道具作为 panelsData初始值。当 props 改变时,新数据将被忽略,因为 panelsData 有自己的状态(嗯,它是一个 useState 钩子!)。

这就是为什么您必须显式调用 changePanel 来更改状态。 这就是整个想法!

如果你想观察 data 并相应地更新状态,你可以使用 useEffect 挂钩 data 作为依赖项(这意味着,它将运行只有当 data 改变时),像这样:

 useEffect(() => {
  changePanel(data);
}, [data]);

原文由 ezakto 发布,翻译遵循 CC BY-SA 4.0 许可协议

我们可以这样做,而不是像@ezakto 提到的那样使用 useEffect() :

 const copyData = JSON.parse(JSON.stringify(data));

if(panelsData !== copyData){
    changePanel(data);
}

这样他们就不会重新呈现,并且您的应用程序会有些高效。

原文由 Koushil Mankali 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进