Javascript 组件没有';当重新渲染状态更改时重新渲染-React
我有Javascript 组件没有';当重新渲染状态更改时重新渲染-React,javascript,reactjs,redux,react-redux,Javascript,Reactjs,Redux,React Redux,我有RowsCont和renderRows renderRows = () => { let result = []; const {rows} = this.props; console.log('RENDER'); console.log(rows); for(let key in rows){ result.push(<Row={rows[key].id} onHover={this.onHo
RowsCont
和renderRows
renderRows = () => {
let result = [];
const {rows} = this.props;
console.log('RENDER');
console.log(rows);
for(let key in rows){
result.push(<Row={rows[key].id}
onHover={this.onHover}
row={rows[key]}/>);
}
return result;
};
....
render(){<div>{this.renderRows()}</div>}
....
function mapStateToProps(state) {
console.log('mapState');
console.log(state.rows.rows);
return {
rows: state.rows.rows,
}
}
一切正常,但是,如果状态更改,组件不会重新渲染。
我确信该状态已更改,因为每次更改时,我都会在map statetoprops
中看到console.log
的新状态,但在renderRows
中看不到console.log
每个行组件都有和
onHover
。如果我将行悬停,它将被重新渲染,并且我将看到具有新值的行的新状态。您的组件不会重新渲染,因为您的对象与以前的对象相同。
在渲染周期中,React对新传入的道具执行差异检查。如果有什么不同,它将重新渲染。在您的情况下,对象与以前是同一个对象
例如:
var rows = {id: 1, value: 'someVal'};
var oldRows = rows;
rows.id = 2;
rows.value = 'someNewVal';
console.log(rows === oldRows); // => true
React在行
和旧行
之间进行差异检查,并查看对象本身是否相同!由于差异检查看到相等,因此不会发生重新渲染
解决此问题的最简单方法是通过对象中的基本体更新属性值
例如,当发生更改时,这将强制重新招标:
function mapStateToProps(state) {
console.log('mapState');
console.log(state.rows.rows);
return {
id: state.rows.rows.id,
value: state.rows.rows.value
}
}
如果绝对需要将对象传递给组件,则可以在redux存储中创建新对象。类似于
state.rows=Object.assign({},oldRows)
的东西应该可以做到这一点。您的组件没有重新排序,因为您的对象与以前的对象相同
在渲染周期中,React对新传入的道具执行差异检查。如果有什么不同,它将重新渲染。在您的情况下,对象与以前是同一个对象
例如:
var rows = {id: 1, value: 'someVal'};
var oldRows = rows;
rows.id = 2;
rows.value = 'someNewVal';
console.log(rows === oldRows); // => true
React在行
和旧行
之间进行差异检查,并查看对象本身是否相同!由于差异检查看到相等,因此不会发生重新渲染
解决此问题的最简单方法是通过对象中的基本体更新属性值
例如,当发生更改时,这将强制重新招标:
function mapStateToProps(state) {
console.log('mapState');
console.log(state.rows.rows);
return {
id: state.rows.rows.id,
value: state.rows.rows.value
}
}
如果绝对需要将对象传递给组件,则可以在redux存储中创建新对象。类似于
state.rows=Object.assign({},oldRows)
的东西应该可以做到这一点。在redux中,你应该永远不要改变状态,所以currentRows[changedIndex].value=action.value代码>是禁止的
以下是一个可能的解决方案:
case 'SET_NEW_ROW_VALUE':
const rows = state.rows.map(
(row, index) => row.id !== action.id ?
row :
{...row, value: action.value}
);
return {...state, rows};
在您的解决方案中,在执行caseSET\u new\u ROW\u VALUE
之后,您没有propstate.rows的新引用。由于react redux
使用浅比较
(=
运算符)检测对象是否已更改,使用您的解决方案,组件将不会重新呈现为状态。行
将与之前相同的对象(相同的引用)在redux中,您应该永远不要更改状态,所以currentRows[changedIndex].value=action.value代码>是禁止的
以下是一个可能的解决方案:
case 'SET_NEW_ROW_VALUE':
const rows = state.rows.map(
(row, index) => row.id !== action.id ?
row :
{...row, value: action.value}
);
return {...state, rows};
在您的解决方案中,在执行caseSET\u new\u ROW\u VALUE
之后,您没有propstate.rows的新引用。当react redux
时,使用浅比较
(==
操作符)检测对象是否已更改,使用您的解决方案,组件将不会重新呈现为状态。此行中的行
将是与之前相同的对象(相同的引用)。result.push(是的,它是rows
*编辑的。在这一行中result.push(是的,它是rows
*编辑的。但是state.rows.rows.value
是未定义的。但是state.rows.value
不是状态,它是另一个变量(currentRows),因为让currentRows=state.rows;
或者我遗漏了什么?实际上currentRows
是你状态的一部分(=>state.rows
),所以如果你变异currentRows
你也会变异状态
哦,通过引用传递:)。谢谢!但是currentRows
不是状态,它是另一个变量(currentRows),因为让currentRows=state.rows;
或者我遗漏了什么?实际上currentRows
是状态的一部分(=>state.rows
),因此,如果您对currentRows
进行变异,您也会对状态进行变异
哦,通过引用传递:)。谢谢!