当属性更改时,React包装器组件HOC不会重新渲染子组件

问题描述

我的包装器组件具有此签名

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());

我希望内容到处都会被替换(下面的第一和第二部分)。 这是渲染功能的一部分

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>
  );

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

解决方法

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

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

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

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...