我是React的新手,正在开发一个应用程序(使用React钩子(,该应用程序基本上是Trello板或看板板的克隆,因此一组列表显示为列,每个列表都有多张卡。用户可以添加新的列表,也可以向列表中添加新的卡片(除了在列表之间拖放卡片之外(,这就是我遇到的问题。
当这个视图加载时,我用数据库中的一个对象以列表对象数组的形式填充状态变量lists
,每个列表对象都有一个卡对象数组,基本结构如下:
[
{
listId: 0,
listTitle: 'List Title',
cards: [
{
cardId: 0,
cardText: 'some text'
},
{
cardId: 1,
cardText: 'some text'
}
]
},
{
listId: 1,
listTitle: 'Another title',
cards: [ ... ]
},
{
listId: 2,
listTitle: 'Yet another',
cards: [ ... ]
}
]
我负责这个视图的组件基本上看起来是这样的:
function Board() {
const [lists, setLists] = useState([]);
const addList = (listTitle) => {
// adds list to db and updates lists state with new array
}
const addCard = (listId, cardText) => {
// adds card to db and updates lists state with new array
}
useEffect(() => {
api.getLists()
.then((listData) => {
setLists(listData)
})
.catch((error) => {
console.log(error);
})
}, []);
return (
<main>
{lists.map((list) => <List key={list.id} listId={list.id} title={list.title} cards={list.cards} addCard={addCard} />)}
<AddElementPanel addElement={addList} />
</main>
);
}
function List({ title, cards, listId, addCard }) => {
return (
<section>
<h2>{title}</h2>
<ul>
{listCards.map((card) => <Card key={card.id} text={card.text} />)}
</ul>
<AddElementPanel listId={listId} addElement={addCard} />
</section>
);
}
function Card({ text }) {
return (<li>{text}</li>);
}
我的问题是,当用户想要添加新的卡或列表时,数据会被插入到数据库中,但我知道如何显示更改的唯一方法是执行setList[...newList]
之类的操作,这当然会导致每个列表和卡重新呈现。这对我来说似乎并不理想,因为如果我将一个新列表或一张新卡添加到一个列表中,未更改的列表将重新呈现。我知道这对目前的设置来说不是什么大不了的事,但如果需要在子组件中发生一些非常昂贵的事情,或者有大量的数据,如何才能更好地构建?
从研究来看,像Redux或另一个州管理库这样的东西可能会更有效地管理这样的州,尽管我不能100%确定这对于一个还没有学习Redux的案例是否准确。我也很好奇,是否有一个更简单的解决方案,或者一个更好的方法来防止这种行为?我试着用React.memo包装List组件,但这似乎没有什么区别,所以我要么做错了,要么没有考虑到影响它的因素。如果有人能给我指明正确的方向,我将不胜感激。
您是否进行了任何性能测试,从而怀疑您对该代码进行了不必要的重新编写?AFAIK,只要您在组件中使用唯一密钥,React的困难算法就会处理此问题。
事实上,useMemo
不应该在这里添加任何改进,因为每当列表/卡片阵列发生变化时,它的依赖关系就会发生变化。