Reactjs React/Redux:如何更新网格中的一个单元格而不重新渲染所有其他单元格
我有一个React/Redux应用程序,在其中我绘制了一个二维网格。网格数据以数组的形式存在于Redux存储中。e、 g.对于3x2网格,可能如下所示:Reactjs React/Redux:如何更新网格中的一个单元格而不重新渲染所有其他单元格,reactjs,optimization,reselect,Reactjs,Optimization,Reselect,我有一个React/Redux应用程序,在其中我绘制了一个二维网格。网格数据以数组的形式存在于Redux存储中。e、 g.对于3x2网格,可能如下所示: state.grid = [ [{value: 1},{value: 2}], [{value: 0},{value: 1}], [{value: 1},{value: 3}] ] case UPDATE_GRID_CELL: { { newValue } = action.payload; return updeep({
state.grid = [
[{value: 1},{value: 2}],
[{value: 0},{value: 1}],
[{value: 1},{value: 3}]
]
case UPDATE_GRID_CELL: {
{ newValue } = action.payload;
return updeep({
'grid': { [columnIndex]: { [rowIndex]: newValue } },
state);
}
用户可以单击网格正方形以更改其值。由于网格可能很大,我只想更新已更改的单元格。但不管我怎么做,整个网格都会更新
我用with来记忆单个选择器,但我认为它不起作用。以下是我的代码的简化版本:
GridCell.js:
class GridCell extends PureComponent {
render() {
const { valueObj } = this.props;
return <span>valueObj.value</span>
}
function mapStateToProps(state, ownProps) {
const { rowIndex, columnIndex } = ownProps;
const valueObj = getValueCached(state, `${columnIndex}_${rowIndex}`);
console.log('which cell', `${columnIndex}_${rowIndex}`);
return {valueObj};
}
export default connect(mapStateToProps)(GridCell);
当用户单击网格方格时,mapStateToProps函数中的哪个单元格日志将写入每个网格单元格的控制台
编辑:我正在使用我的减速器内部更新值,如下所示:
state.grid = [
[{value: 1},{value: 2}],
[{value: 0},{value: 1}],
[{value: 1},{value: 3}]
]
case UPDATE_GRID_CELL: {
{ newValue } = action.payload;
return updeep({
'grid': { [columnIndex]: { [rowIndex]: newValue } },
state);
}
我还尝试使用connect作为简单道具获取值:
function mapStateToProps(state, ownProps) {
const { rowIndex, columnIndex } = ownProps;
return {state.grid[columnIndex][rowIndex].value};
}
我检查了一下是否有任何道具或状态发生了变化:
componentDidUpdate(prevProps, prevState) {
console.log('componentWillUpdate');
console.log('new', JSON.stringify(this.props));
console.log('old', JSON.stringify(prevProps));
console.log('changed props', JSON.stringify(this.props) !== JSON.stringify(prevProps));
console.log('state');
console.log('new', JSON.stringify(this.state));
console.log('old', JSON.stringify(prevState));
console.log('changed state', JSON.stringify(this.state) !== JSON.stringify(prevState));
}
此日志为false,但呈现方法仍在运行,如控制台日志所示。我很困惑,因为我认为pureComponent的要点是,它只有在状态或道具发生变化时才会渲染
我希望备忘录为未受影响的单元格提供相同的值,并且不会触发组件更新。但我肯定错过了什么
我不知道如何测试备忘录是否有效。如果我在getValueCached中放置一个console.log,它会为每个单元格写入,但我不知道它是否会这样做
是否有任何方法可以防止每个网格单元组件在单个值更改时更新?谢谢你的建议
编辑:从评论/答案和进一步调查来看,重新渲染似乎是由数组道具引起的。我创建了一个示例,用一个最小的沙盒示例来说明这一点。我认为您误解了MapStateTrops函数。 每次redux状态更新都会调用它,它必须弄清楚该状态的值是否更改。因此,它必须为每个单元格调用每个MapStateTops 但这并不意味着它会重新发布该组件。 如果MapStateTops的先前和当前返回值相同,则更新将中止 因此,调用MapStateTops是正确的。检查单元格是否已重新排序。您还可以删除getValueCached包装器并直接使用state.grid[identifiers[0]][identifiers[1]]访问网格。这将比缓存版本快,因为它只是一个直接访问。而且缓存版本不会给您带来任何好处,因为它不是一个繁重的计算
连接最高的组件可能会更快,如果需要,jsut会让它重新加载。另一个选项是使用react窗口仅渲染当前可见的网格项,这将大大提高性能 为什么不连接MyGrid,而只是将基本值作为简单的道具传递给GridCell组件?我想说,在连接中包装每个网格单元是这里的关键问题。你能告诉我们,你如何更新值吗?谢谢。网格单元格的render方法中的console.log显示每个单元格都在重新渲染,但我不知道为什么,因为在我看来,组件道具和MapStateToProps的返回没有改变。你能在沙盘中重现这一点吗?那么你如何更新存储中的网格值呢?我的实际代码还有很多内容,包括两个数组属性。但是这些都没有改变,只有简单的“值”道具。我用沙盒创建了一个新问题,因为问题似乎与数组道具有关,而不是记忆: