如何解决React Child 在操作 child 中的 props 时正在更新 Parent State不需要的
以下代码位于 https://codesandbox.io/s/child-updating-parent-dont-want-pfdxd 我面临的问题是,当我对子组件(page2)进行排序时,它还会更新父组件(App)上的状态。我想避免状态更新,因为其他子组件(第 1 页)应该显示未排序的数据。我想过在 App.js 上有两个具有相同数据(两个名称和两个数字)的状态。然后将 1 组状态(名称和数字)用于第 1 页,另一组用于第 2 页。这似乎是多余和不必要的,但我不确定在第 2 页上排序时如何避免状态更新。有没有办法避免操作子组件中的数据时状态更新?
/*Parent*/
class App extends React.Component {
constructor() {
super();
this.state = {
numbers: [1,2,3,4,5,6,7,8,9,10],names: ["john","sally","bill","rebecca"]
};
}
render() {
const { numbers,names } = this.state;
return (
<Router>
<div className="App">
<Header />
<Switch>
<Route
path="/page1"
exact
render={(routeProps) => (
<Page1 digits={numbers} people={names} {...routeProps} />
)}
/>
<Route
path="/page2"
exact
render={(routeProps) => (
<Page2 digits={numbers} people={names} {...routeProps} />
)}
/>
</Switch>
</div>
</Router>
);
}
}
export default App;
这里是第一个接收 props 的组件
/*child 1*/
const page1 = ({ people,digits }) => {
return (
<div>
<h1>
Number Should Be "1" And Name Should Be "john" On This Page Regardless
Of Sort On Page 2
</h1>
<p>Number: {digits[0]}</p>
<p>Name: {people[0]}</p>
</div>
);
};
export default page1;
这里是接收 props 的第二个组件
/*child 2*/
const Page2 = ({ people,digits }) => {
/* when uncommented the sort will also change state on App.js ---
I want state on App.js to remain in original state aft sorting*/
/* --- UNCOMMENT BELOW TO SORT --- */
/*people.sort((a,b) => b.toLowerCase().localeCompare(a.toLowerCase()));
digits.sort((a,b)=>b-a)*/
return (
<div>
<h1>
Number Should Be "10" And Name Should Be "sally" On This Page When Sort
Is Uncommented
</h1>
<p>Number: {digits[0]}</p>
<p>Name: {people[0]}</p>
</div>
);
};
export default Page2;
解决方法
在 Javascript 中,sort
方法执行就地排序。因此,当您执行 people.sort
时,您实际上最终会修改传递的 people
道具。由于数组是通过引用传递的,people
的所有其他引用都将显示新的排序值。
要解决此问题,您应该更改传递的道具的本地副本,以防止出现此类意外结果。
const Page2 = ({ people,digits }) => {
const sortedPeople = [...people].sort((a,b) => b.toLowerCase().localeCompare(a.toLowerCase()))
const sortedDigits = [...digits].sort((a,b)=>b-a);
return (
<div>
<h1>
Number Should Be "10" And Name Should Be "sally" On This Page When Sort
Is Uncommented
</h1>
<p>Number: {sortedDigits[0]}</p>
<p>Name: {sortedPeople[0]}</p>
</div>
);
};
export default Page2;
为了进一步解释上述方法中发生的事情,
我们现在不是直接改变 prop,而是创建数组的副本,在本例中为 people
和 digits
,通过使用像 [...people]
这样的 ES6 扩展运算符并排序这个新副本。
const sortedPeople = [...people].sort((a,b) => b.toLowerCase().localeCompare(a.toLowerCase()))
附注。您也可以执行 Array.from(people)
或 people.slice()
以获得相同的结果。
请记住,您可以通过使用 useMemo
钩子在 React 中进一步优化它的渲染性能并执行类似操作
const sortedPeople = useMemo(() => [...people].sort((a,b) => b.toLowerCase().localeCompare(a.toLowerCase())),[people]);
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。