Redux无法同步更新组件

时间:2018-07-19 01:08:33

标签: reactjs redux react-redux

我的印象是redux是同步的,但在这种情况下似乎并非如此。我有这个:

loadData() {
  const filterData = {};

  Object.values(this.props.filters).map(f => {
     filterData[f.filter] = f.selectedValue || '';
   });

   this.props.fetchData({filters: filterData}); //redux call to load data
}

filterOnSubmit(filter, value, display) {
 const newFilter = { filter, selectedValue: value, display };
 this.props.updateFilter(newFilter);
 this.loadData();
} 

但是当我查看redux devtools时,f的值不包括设置的所选值。如果我延迟了映射(或通过将loadData放置在setState回调中而延迟了它),那么它也在那里。

动作和减速器供参考:

case UPDATE_FILTER: {
   const newFilter = { ...state[action.payload.filter], ...action.payload };
   return { ...state, [action.payload.filter]: newFilter };
}

export function updateFilter(newFilterData) {
  return {
    type: UPDATE_FILTER,
    payload: newFilterData
  };
}

3 个答案:

答案 0 :(得分:1)

您使用的方法正确,请使用componentDidUpdate来发起新的提取请求。您可能会缺少的一个条件是更改滤镜属性的条件。

文档提醒您:

  

您可以在componentDidUpdate()中立即调用setState(),但请注意   必须将其包装在上面示例中所示的条件下,或者   您将导致无限循环。

根据您的情况,可能取决于过滤器的形状,如下所示:

componentDidUpdate(prevProps) {
  if (this.props.filter !== prevProps.filter)
    this.loadData();
}

取决于外部代码,您还可以考虑在if内部使用深度比较。但是,当然,最好的方法是保持===比较并从外部优化mapStateToProps(例如使用记忆化)。

答案 1 :(得分:1)

尽管redux存储更新是同步的,但更改不会反映在同一React周期中,但更新会进入重新渲染状态,并调用update lifecycle方法。

更新商店后,您可以使用生命周期方法(如componentDidUpdate (or componentWillReceiveProps which is now soon to be deprecated)来调用商店更新中需要调用的操作,或者直接将过滤器传递给loadData函数

loadData(filters) {
  const filterData = {};

  Object.values(filters).map(f => {
     filterData[f.filter] = f.selectedValue || '';
   });

   this.props.fetchData({filters: filterData}); //redux call to load data
}

filterOnSubmit(filter, value, display) {
 const newFilter = { filter, selectedValue: value, display };
 this.props.updateFilter(newFilter);
 this.loadData(newFilter);
} 

使用componentDidUpdate,您可以这样写

componentDidUpdate(prevProps) {
   // you have to perform an isEqual check since simply using '===' will not work for comparing arrays
   if(!_.isEqual(prevProps.filters, this.props.filters)) {
       this.loadData();
   }
}
loadData() {
  const filterData = {};

  Object.values(this.props.filters).map(f => {
     filterData[f.filter] = f.selectedValue || '';
   });

   this.props.fetchData({filters: filterData}); //redux call to load data
}

filterOnSubmit(filter, value, display) {
 const newFilter = { filter, selectedValue: value, display };
 this.props.updateFilter(newFilter);
} 

答案 2 :(得分:0)

按照萨玛布所说的做,或移动

Object.values(this.props.filters).map(f => {
      console.log(f);
      filterData[f.filter] = f.selectedValue || '';
    });

渲染功能。