nextProps 始终与 componentWillReceiveProps 中的 this.props 相同,即使道具已更改
nextProps always identical to this.props in componentWillReceiveProps, even when the props have changed
我的 React 应用程序中有一个组件可以为用户呈现总价值。当该值上升时,我想发出声音。我认为在显示总数的组件中是播放噪音的好地方。
所以我在组件中添加了一个componentWillReceiveProps
方法,在其中,我计算了两个总数:total
是从this.props
计算的,nextTotal
是从nextTotal
计算的nextProps
.
令我惊讶的是,即使值发生变化,总计也发生变化,nextTotal
和 total
始终 相同。所以我想在总数上升时开火的条件永远不会发生。
我写了一个简单的单组件示例。 JSfiddle.
var Hello = React.createClass({
componentWillReceiveProps: function(nextProps) {
var total = 0;
this.props.vals.forEach(val => total+= val);
var nextTotal = 0;
nextProps.vals.forEach(val => nextTotal+= val);
console.log(total, nextTotal)
if (nextTotal > total) {
//never runs
console.log('moving up');
}
},
render: function() {
var total = 0;
vals.forEach(val => total+= val)
return (
<div>{total}</div>
)
}
});
var vals = [1, 21, 452, 123];
setInterval(renderReact, 1000)
function renderReact() {
vals.push(10);
ReactDOM.render(
<Hello
vals={vals}
/>,
document.getElementById('container')
);
}
如您所见,它每秒向 vals
数组添加 10,这意味着总数增加 1。但是如果您打开控制台,您会看到 total
和nextTotal
始终相同,并且 moving up
永远不会被记录。
我显然误解了某事,如果有人能解释我的误解是什么,以及我应该如何实现我的目标,那就太好了。
如评论中所述(@PitaJ),您的问题是您第一次传入一个数组,然后更改该数组 - 而不是使用新的 属性 调用。您已经进入了您的组件作为其现有对象持有引用的对象 属性 并更改了它的内容。
在您的 fiddle 中,试试这个:
function renderReact() {
vals.push(10);
ReactDOM.render(
<Hello
vals={vals.concat([])}
/>,
document.getElementById('container')
);
}
每次将数组的副本作为道具传入,您会发现它们有适当的不同。
这实际上是使用 react 时的一个重要错误来源,如果不仔细编写 reducer,即使将 redux 与它一起使用时也会突然出现。使用不可变数据结构是避免它的一种方法。
我的 React 应用程序中有一个组件可以为用户呈现总价值。当该值上升时,我想发出声音。我认为在显示总数的组件中是播放噪音的好地方。
所以我在组件中添加了一个componentWillReceiveProps
方法,在其中,我计算了两个总数:total
是从this.props
计算的,nextTotal
是从nextTotal
计算的nextProps
.
令我惊讶的是,即使值发生变化,总计也发生变化,nextTotal
和 total
始终 相同。所以我想在总数上升时开火的条件永远不会发生。
我写了一个简单的单组件示例。 JSfiddle.
var Hello = React.createClass({
componentWillReceiveProps: function(nextProps) {
var total = 0;
this.props.vals.forEach(val => total+= val);
var nextTotal = 0;
nextProps.vals.forEach(val => nextTotal+= val);
console.log(total, nextTotal)
if (nextTotal > total) {
//never runs
console.log('moving up');
}
},
render: function() {
var total = 0;
vals.forEach(val => total+= val)
return (
<div>{total}</div>
)
}
});
var vals = [1, 21, 452, 123];
setInterval(renderReact, 1000)
function renderReact() {
vals.push(10);
ReactDOM.render(
<Hello
vals={vals}
/>,
document.getElementById('container')
);
}
如您所见,它每秒向 vals
数组添加 10,这意味着总数增加 1。但是如果您打开控制台,您会看到 total
和nextTotal
始终相同,并且 moving up
永远不会被记录。
我显然误解了某事,如果有人能解释我的误解是什么,以及我应该如何实现我的目标,那就太好了。
如评论中所述(@PitaJ),您的问题是您第一次传入一个数组,然后更改该数组 - 而不是使用新的 属性 调用。您已经进入了您的组件作为其现有对象持有引用的对象 属性 并更改了它的内容。
在您的 fiddle 中,试试这个:
function renderReact() {
vals.push(10);
ReactDOM.render(
<Hello
vals={vals.concat([])}
/>,
document.getElementById('container')
);
}
每次将数组的副本作为道具传入,您会发现它们有适当的不同。
这实际上是使用 react 时的一个重要错误来源,如果不仔细编写 reducer,即使将 redux 与它一起使用时也会突然出现。使用不可变数据结构是避免它的一种方法。