我正在处理一个有很多可编辑值的大json(*大意味着> 1000),完全在同一页面上呈现,所以我的状态只是{ data: bigBigJson }
。
初始渲染很长但是没问题。
问题是当输入触发onChange
(和redux动作)时,该值会在状态中更新,整个渲染会再次发生。
我想知道人们如何处理这个问题?是否有简单的解决方案(甚至不一定是最佳实践)。
注意:
json文档由外部API提供,我无法更改
我可以将状态分成几个子状态(它是多个级别的json),但希望有一个更简单/更快的解决方案(我知道它可能是一个最好的做法虽然)
我正在使用react和redux,而不是immutable.js但是一切都是不可变的(显然)
-
更新(关于DSS答案)
•(案例1)让我们说状态是:
{
data: {
key1: value1,
// ...
key1000: value1000
}
}
如果更新了keyN
,那么所有状态都会被重新渲染吗? reducer会返回类似的东西:
{
data: {
...state.data,
keyN: newValueN
}
这是一回事,但事实并非如此。
•(案例2)状态更像(过度简化):
{
data: {
dataSet1: {
key1: value1,
// ...
key10: value1000
},
// ...
dataSet100: {
key1: value1,
// ...
key10: value1000
}
}
}
如果dataN.keyN
更新,我会返回reducer
{
data: {
...state.data,
dataN: {
...state.data.dataN,
keyN: newValueN
}
}
}
我想我做错了,因为它看起来不太好看。 它会改变这样的事情:
// state
{
dataSet1: {
key1: value1,
// ...
key10: value1000
},
// ...
dataSet100: {
key1: value1,
// ...
key10: value1000
}
}
// reducer
{
...state,
dataN: {
...state.dataN,
keyN: newValueN
}
}
最后,为了更具体地说明我的情况,这里更多的是我的减速机看起来像(仍然有点简化):
import get from 'lodash/fp/get'
import set from 'lodash/fp/set'
// ...
// reducer:
// path = 'values[3].values[4].values[0]'
return {
data: set(path, {
...get(path, state.data),
value: newValue
}, state.data)
}
•如果您想知道,我不能只使用:
data: set(path + '.value', newValue, state.data)
因为其他属性也需要更新。
答案 0 :(得分:5)
一切都被重新渲染的原因是因为商店中的所有内容都会发生变化。它看起来可能一样。所有属性可能具有相同的值。但所有对象引用都已更改。也就是说,即使两个对象具有相同的属性,它们仍然具有不同的身份。
由于React-Redux使用对象标识来确定对象是否已更改,因此每当对象未更改时,应始终确保使用相同的对象引用。由于Redux状态必须是不可变的,因此在新状态下使用旧对象是保证不会引起问题的。不可变对象可以重用,可以重用整数或字符串。
要解决您的困境,您可以在reducer中查看JSON和商店状态子对象并进行比较。如果它们相同,请确保使用商店对象。通过重用相同的对象,React-Redux将确保不会重新呈现代表这些对象的组件。这意味着如果这1000个对象中只有一个发生更改,则只会更新一个组件。
还要确保正确使用React key
属性。这1000个项目中的每一个都需要自己的ID,从JSON到JSON保持不变。
最后,考虑让你的州本身更适合这种更新。您可以在加载和更新状态时转换JSON。例如,您可以存储由ID键控的项目,这将使更新过程更快。