当 redux 状态更新时,React componentWillReceiveProps 将接收不触发的道具
React componentWillReceiveProps will receive props not triggering when redux state updates
我有一个存储 actions
,这些操作应该在每次添加新的时循环执行。
我有一个组件 MessageListView
,它位于一个名为 MessageView
的父级中。当一个新动作添加到我的 socketActions.queue
数组时,componentWillRecieveProps
应该触发,但它没有。
这是我的减速器的样子:
/* Reducer */
const initialState = {
queue: [{
type: 'alert',
action: 'alert',
completed: false, // Set to true or just delete this object when the action has been completed
data: {
message: "the data object dynamically changes based on the type"
}
}]
};
export default (state = initialState, action) => {
switch (action.type) {
case ADD_ACTION:
let queue = state.queue
// action.data['completed'] = false
queue.push(action.data)
console.log("Just updated queue", action.data)
return {
...state,
queue: queue,
latestAction: new Date()
}
我的组件是这样连接到商店的:
function mapStateToProps(state){
console.log(state, "State inside messagelistview.js")
return {
actionsQueue: state.socketActions.queue,
latestAction: state.socketActions.latestAction
}
};
const mapDispatchToProps = (dispatch) => {
return bindActionCreators({ completeAction }, dispatch);
};
export default connect(
mapStateToProps,
mapDispatchToProps
)(MessageListView);
因此,当我发送新的 ADD_ACTION
操作时,我的状态会更新并 redux-logger
打印出新旧状态,告诉我它们是一样的? ! 。我不知道为什么在我更改 latestAction 值和队列数组后它会这样做。这就是 componentWillRecieveProps 不起作用的原因,但我无法弄清楚为什么状态相同?!
不能 100% 确定这是否能解决任何问题,但我认为您没有正确地将 state.queue 复制到全新的变量队列中。
我建议这样做:
let queue = state.queue.slice()
...看看有什么变化吗?现在您的 queue
变量仍然与 state.queue
相同
您不更改 reducer 中的队列标识。试试这个代码:
case ADD_ACTION:
let queue = state.queue
// action.data['completed'] = false
queue.push(action.data)
console.log("Just updated queue", action.data)
return {
...state,
queue: [...queue], // <-- here we copy array to get new identity
latestAction: new Date()
}
你应该总是浅拷贝改变的对象。参见 http://redux.js.org/docs/Troubleshooting.html#never-mutate-reducer-arguments
问题是当你这样做时你正在改变你的状态:
let queue = state.queue
// action.data['completed'] = false
queue.push(action.data)
当您直接改变现有状态时,Redux 不会检测到状态差异,也不会通知您的组件商店已更改。
因此,您可以使用以下选项来创建新的 queue
数组:
case ADD_ACTION:
return {
...state,
queue: state.queue.concat(action.data),
latestAction: new Date()
}
或使用 ES6 糖:
case ADD_ACTION:
return {
...state,
queue: [...state.queue, action.data]
latestAction: new Date()
}
连接的组件会浅层检查 (===) 状态是否已更新,并仅在检查失败时才呈现包装组件。在你的情况下,你正在改变你的队列,导致平等检查通过。
如果你像这样改变你的减速器,它将起作用:
state.queue = state.queue.concat(action.data);
或使用 ES6 语法:
state = { ...state, queue: [...state.queue, action.data] };
我有一个存储 actions
,这些操作应该在每次添加新的时循环执行。
我有一个组件 MessageListView
,它位于一个名为 MessageView
的父级中。当一个新动作添加到我的 socketActions.queue
数组时,componentWillRecieveProps
应该触发,但它没有。
这是我的减速器的样子:
/* Reducer */
const initialState = {
queue: [{
type: 'alert',
action: 'alert',
completed: false, // Set to true or just delete this object when the action has been completed
data: {
message: "the data object dynamically changes based on the type"
}
}]
};
export default (state = initialState, action) => {
switch (action.type) {
case ADD_ACTION:
let queue = state.queue
// action.data['completed'] = false
queue.push(action.data)
console.log("Just updated queue", action.data)
return {
...state,
queue: queue,
latestAction: new Date()
}
我的组件是这样连接到商店的:
function mapStateToProps(state){
console.log(state, "State inside messagelistview.js")
return {
actionsQueue: state.socketActions.queue,
latestAction: state.socketActions.latestAction
}
};
const mapDispatchToProps = (dispatch) => {
return bindActionCreators({ completeAction }, dispatch);
};
export default connect(
mapStateToProps,
mapDispatchToProps
)(MessageListView);
因此,当我发送新的 ADD_ACTION
操作时,我的状态会更新并 redux-logger
打印出新旧状态,告诉我它们是一样的? ! 。我不知道为什么在我更改 latestAction 值和队列数组后它会这样做。这就是 componentWillRecieveProps 不起作用的原因,但我无法弄清楚为什么状态相同?!
不能 100% 确定这是否能解决任何问题,但我认为您没有正确地将 state.queue 复制到全新的变量队列中。
我建议这样做:
let queue = state.queue.slice()
...看看有什么变化吗?现在您的 queue
变量仍然与 state.queue
您不更改 reducer 中的队列标识。试试这个代码:
case ADD_ACTION:
let queue = state.queue
// action.data['completed'] = false
queue.push(action.data)
console.log("Just updated queue", action.data)
return {
...state,
queue: [...queue], // <-- here we copy array to get new identity
latestAction: new Date()
}
你应该总是浅拷贝改变的对象。参见 http://redux.js.org/docs/Troubleshooting.html#never-mutate-reducer-arguments
问题是当你这样做时你正在改变你的状态:
let queue = state.queue
// action.data['completed'] = false
queue.push(action.data)
当您直接改变现有状态时,Redux 不会检测到状态差异,也不会通知您的组件商店已更改。
因此,您可以使用以下选项来创建新的 queue
数组:
case ADD_ACTION:
return {
...state,
queue: state.queue.concat(action.data),
latestAction: new Date()
}
或使用 ES6 糖:
case ADD_ACTION:
return {
...state,
queue: [...state.queue, action.data]
latestAction: new Date()
}
连接的组件会浅层检查 (===) 状态是否已更新,并仅在检查失败时才呈现包装组件。在你的情况下,你正在改变你的队列,导致平等检查通过。
如果你像这样改变你的减速器,它将起作用:
state.queue = state.queue.concat(action.data);
或使用 ES6 语法:
state = { ...state, queue: [...state.queue, action.data] };