Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/assembly/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Reactjs React/Redux:如何更新网格中的一个单元格而不重新渲染所有其他单元格_Reactjs_Optimization_Reselect - Fatal编程技术网

Reactjs React/Redux:如何更新网格中的一个单元格而不重新渲染所有其他单元格

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({

我有一个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({
        '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的返回没有改变。你能在沙盘中重现这一点吗?那么你如何更新存储中的网格值呢?我的实际代码还有很多内容,包括两个数组属性。但是这些都没有改变,只有简单的“值”道具。我用沙盒创建了一个新问题,因为问题似乎与数组道具有关,而不是记忆: