我正在我的componentDidMount函数中设置redux状态,然后尝试立即访问并且无法访问。我去除了一些不必要的复杂性,但这是基本设置:
// URL page?id=1
componentDidMount() {
this.props.setFilter({ location: this.props.location.search.id) });
console.log('in mount', this.props.filter);
}
// Action
export function setFilter(filterData) {
return {
type: SET_FILTERS,
payload: filterData
};
}
// Reducer
export default function(state = INITIAL_STATE, action = {}) {
switch(action.type) {
case SET_FILTERS: {
const newState = { ...state, filter: action.payload };
console.log('reducer state', newState);
return newState;
}
...
}
这将输出
reducer state { location: 1 }
in mount {}
但是如果我将componentDidMount更改为
componentDidMount() {
this.props.setFilter({ location: 1 });
setTimeout(() => { console.log(this.props.filter), 0; });
}
它按预期方式工作并输出
reducer state { location: 1 }
in mount { location: 1 }
为什么会这样?
谢谢!
答案 0 :(得分:1)
this.props
不能直接由setFilter
更新。
分派到商店的操作会触发mapStateToProps
重新运行,收集新值并将其合并到组件属性中。
console.log('in mount', this.props.filter);
在此循环完成之前运行。
setTimeout(() => { console.log(this.props.filter), 0; });
在此循环完成后运行。
尝试一下。
componentDidMount() {
const propsCopy = this.props;
this.props.setFilter({ location: 1 });
console.log("before", this.props === propsCopy);
setTimeout(() => { console.log("after", this.props === propsCopy) }, 0);
}
您将获得before true
和after false
。
因此,尽管调度是同步的,但setTimout前后的props对象是不同的,只有新的props才设置了过滤器。