首页 > 解决方案 > 为什么我不能在没有超时的情况下访问 componentDidMount 中更新的 redux 数据?

问题描述

我在我的 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 }

为什么会这样?

谢谢!

标签: reactjsreduxreact-redux

解决方案


this.props is not updated directly by setFilter.

The action dispatched to the store triggers mapStateToProps to re-run, collect the new value, and merge it into the component props.

console.log('in mount', this.props.filter); runs before this cycle is complete.

setTimeout(() => { console.log(this.props.filter), 0; }); runs after this cycle is complete.

try this..

componentDidMount() {
  const propsCopy = this.props;
  this.props.setFilter({ location: 1 });
  console.log("before", this.props === propsCopy);
  setTimeout(() => { console.log("after", this.props === propsCopy) }, 0);
}

you'll get before true & after false.

so although the dispatch is synchronous, the props objects before and after the setTimout are different, and it's only the new props that have the filter set.


推荐阅读