为什么没有超时就无法访问componentDidMount中更新的redux数据?

时间:2018-12-05 02:06:53

标签: reactjs redux react-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 }

为什么会这样?

谢谢!

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 trueafter false

因此,尽管调度是同步的,但setTimout前后的props对象是不同的,只有新的props才设置了过滤器。