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

Ada*_*rsh 15 reactjs react-hooks

每次我在 data prop 中获取新数据但组件在我调用之前不会重新渲染 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>
        );
      })}
    </>
  );
}
Run Code Online (Sandbox Code Playgroud)

但是当我像下面一样取下钩子时它就起作用了

function StepPanel({ data, getTranslations }) {
 
  return (
    <>
      {data.map(details => { ... })}
    </>
         )
}
Run Code Online (Sandbox Code Playgroud)

我想实现一个功能,当我在 data props 中获取新数据时,组件会重新渲染,而且当我需要在内部重新渲染时,即像我更改一样panelId = 8,然后它也会重新渲染,是否可以使用这种方法?

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

控制台图像

eza*_*kto 44

这是因为当你这样做时:

const [panelsData, changePanel] = useState(data);
Run Code Online (Sandbox Code Playgroud)

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

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

如果你想观察dataprop 并相应地更新状态,你可以使用useEffect带有dataas 依赖的钩子(这意味着它只会在data发生变化时运行),如下所示:

useEffect(() => {
  changePanel(data);
}, [data]);
Run Code Online (Sandbox Code Playgroud)

祝你好运!