[英]How can i only re-render the new child component when mapping an array from Redux state?
Context语境
I have a Redux state in which i have an array of items.我有一个 Redux state,其中我有一系列项目。 Everytime you click a link in the menu, an item gets added to this array.每次单击菜单中的链接时,都会将一个项目添加到此数组中。
In one of my components, which is connected to the store using connect(mapStateToProps)(Component)
I map through this array and load the child components.在我的一个组件中,它使用connect(mapStateToProps)(Component)
I map 通过此数组连接到商店并加载子组件。 These child components fetch data from an API.这些子组件从 API 获取数据。
Problem问题
Everytime a new item gets added to the array, all the child components re-render, because the array that it maps changes.每次将新项目添加到数组时,所有子组件都会重新渲染,因为它映射的数组会发生变化。 I only want the newly added item to render and the rest persist as they are.我只想渲染新添加的项目,并且 rest 保持原样。 I know you can do something with useMemo, but I'm not sure how to correctly use that with mapping.我知道你可以用 useMemo 做一些事情,但我不确定如何正确地使用它来映射。
Thanks to anyone who can help me!感谢任何可以帮助我的人!
You can use pure component for each item:您可以为每个项目使用纯组件:
const id = ((id) => () => id++)(1); const Item = React.memo(function Item({ item, increase }) { const rendered = React.useRef(0); rendered.current++; return ( <li> {item.id} - rendred {rendered.current} count:{' '} {item.count} <button onClick={() => increase(item.id)}> increase count </button> </li> ); }); const App = () => { const [items, setItems] = React.useState([]); const addItem = () => setItems((items) => [{ id: id(), count: 0 }, ...items]); //use useCallback to create an increase function that // never changes so you'll never pass a new increase // function to item const increase = React.useCallback( //pass callback to state setter so items is not // a dependency of the useCallback (id) => setItems((currentItems) => currentItems.map((item) => item.id === id? {...item, count: item.count + 1 }: item ) ), [] ); return ( <div> <div> <button onClick={addItem}>+</button> </div> <div> {items.map((item) => ( <Item key={item.id} item={item} increase={increase} /> ))} </div> </div> ); }; ReactDOM.render(<App />, document.getElementById('root'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.4/umd/react.production.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.4/umd/react-dom.production.min.js"></script> <div id="root"></div>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.