【问题标题】:React wrapper component (HOC) does not re-render child component when it's props are changingReact 包装器组件 (HOC) 在 props 发生变化时不会重新渲染子组件
【发布时间】:2020-08-20 17:46:22
【问题描述】:

我的包装组件有这个签名

const withReplacement = <P extends object>(Component: React.ComponentType<P>) =>
  (props: P & WithReplacementProps) => {...}

顺便说一句,完整的例子在这里https://codepen.io/xitroff/pen/BaKQNed

它从参数组件的道具中获取原始内容

interface WithReplacementProps {
  getContent(): string;
}

然后在按钮点击时调用setContent函数。

const { getContent, ...rest } = props;
const [ content, setContent ] = useState(getContent());

我希望所有内容都会被替换(下面的第 1 和第 2 部分)。 这是渲染函数的一部分

return (
      <>
        <div>
          <h4>content from child</h4>
          <Component
            content={content}
            ReplaceButton={ReplaceButton}
            {...rest as P}
          />
          <hr/>
        </div>

        <div>
          <h4>content from wrapper</h4>
          <Hello
            content={content}
            ReplaceButton={ReplaceButton}
          />
          <hr/>
        </div>
      </>
    );

Hello 组件很简单

<div>
  <p>{content}</p>
  <div>
    {ReplaceButton}
  </div>
</div>

这就是包装的方式

const HelloWithReplacement = withReplacement(Hello);

但问题是内容仅在第二部分被替换。第一个保持不变。

在主 App 组件中,我也在加载 20 秒后替换内容。

const [ content, setContent ] = useState( 'original content');

  useEffect(() => {
    setTimeout(() => {
      setContent('...too late! replaced from main component');
    }, 10000);
  }, []);

...当我像这样调用我的包装组件时

return (
    <div className="App">
      <HelloWithReplacement
        content={content}
        getContent={() => content}
      />
    </div>
  );

它也有问题 - 第一部分正在更新,第二部分没有。

【问题讨论】:

    标签: reactjs react-hooks higher-order-functions higher-order-components


    【解决方案1】:

    您似乎正在用应用程序的外部状态覆盖 withReplacement 内部状态

    <HelloWithReplacement
        content={content} // Remove this to stop overriding it
        getContent={() => content}
      />
    

    无论如何使用两种不同的状态看起来很奇怪,最好只在一个地方管理你的应用状态

    【讨论】:

    • 我不需要更新两个地方的状态。我只需要两件事:1)从参数组件中获取内容 2)通过包装器内的操作将其替换为参数组件内的内容。其余部分是出于调试和解释目的而添加的。是的,它看起来很奇怪,但显示了具体问题。如果您可以通过删除“调试”的东西来实现这一点,那就完美了:)
    • 您是否尝试从 HelloWithReplacement 中删除 content 属性?
    • 谢谢,这解决了问题,这是一个没有修复的简短示例 btw codepen.io/xitroff/pen/bGpBVPz
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-07-09
    • 1970-01-01
    • 2020-02-27
    • 2021-06-21
    • 2021-09-20
    相关资源
    最近更新 更多