如何解决父功能组件中的子组件不会在 Props 更改时重新渲染
我正在动态生成 HOC 父级的子组件(见下文)。我将道具直接传递给其中一个孩子并将道具放入其中。我希望看到孩子重新渲染道具的变化,但事实并非如此。
代码是否有误?
ParentComponent
...
const ParentComponent = ({children}) => {
const [state1,setState1] = useState(true);
...
const changeOpacity = event => setState1(!state1);
const renderChildren = React.useCallback(() => React.Children.toArray(children).map((child,index) => (
<div key={index} style={{opacity: `${state1 ? 0 : 1}`}}>
{child}
</div>
)),[state1]);
return (
<div>
<Button onClick={changeOpacity}>Toggle Opacity</Button>
{renderChildren()}
</div>
);
};
App.js
...
const App = () => {
const [prop1,setProp1] = useState(123);
return (
<ParentComponent>
<Child1 prop1={prop1} setProp1={setProp1} />
<Child2 />
</ParentComponent>
);
};
解决方法
在您的 ParentComponent
中,children
被克隆,然后用于作为 renderChildren 函数返回值的一部分进行渲染。由于计算子组件的逻辑不会在将 props 更改为 child 时运行,因此您的子组件不会受到其 prop 更改的影响。
您可以将 children
依赖项添加到 useCallback
,它会正常工作。
const { useState,useCallback } = React;
const ParentComponent = ({children}) => {
const [state1,setState1] = useState(true);
const changeOpacity = event => setState1(!state1);
const renderChildren = useCallback(() => React.Children.map(children,(child,index) => (
<div key={index} style={{opacity: `${state1 ? 0 : 1}`}}>
{child}
</div>
)),[children,state1]);
return (
<div>
<button onClick={changeOpacity}>Toggle Opacity</button>
{renderChildren()}
</div>
);
};
const Child1 = ({prop1,setProp1}) => <div>{prop1} <button onClick={() => setProp1(234)}>Click</button></div>;
const Child2 = () => <div>Hello</div>
const App = () => {
const [prop1,setProp1] = useState(123);
return (
<ParentComponent>
<Child1 prop1={prop1} setProp1={setProp1} />
<Child2 />
</ParentComponent>
);
};
ReactDOM.render(<App />,document.getElementById('app'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.3/umd/react-dom.production.min.js"></script>
<div id="app" />
是否有什么阻碍您采用以下方法;
const ParentComponent = ({children}) => {
const [state1,setState1] = useState(true);
...
const changeOpacity = event => setState1(!state1);
const renderChildren = useCallback(() => React.Children.toArray(children).map((child,index) => (
<div key={index}>
{child}
</div>
)),[children]);
return (
<div>
<Button onClick={changeOpacity}>Toggle Opacity</Button>
{state1 && renderChildren()}
</div>
);
};
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。