首页 > 解决方案 > Screen doesnt re-render even props changed?

问题描述

I'm currently facing a problem where the screen doesnt re-render to load the new added value to array. Even tried with componentWillReceiveProps and trigger a this.forceUpdate() manually doesn't help. The screen only show the new value when I restart the app

this.props.addNewRecord({ 
    recordDetails: { ...this.props.recordDetails, type: this.state.type },
    records: this.props.records
  });

return (
  <View>
    {
      this.props.records.map((x, i) => {
        return (
          <View style={{ flexDirection: 'row' }}>
            <Text>{`${i}: `}</Text>
            <Text>{x.id}</Text>
          </View>
        );
      })
    }
  </View>
);

const mapStateToProps = ({ account, settings, main }) => {
  const year = moment().year();
  const month = moment().format('MMM');

  return {
    records: account.records[year][month].records,
  };
};

export default connect(mapStateToProps)(SummaryScreen);

account.records has the following structure

{
  2018: {
    Jan: {
      records: [{...}, {...}]
    }
  }
}

And below is the adding record part

const addNewRecord = ({ recordDetails, records }) => {
  const year = moment(recordDetails.date).year();
  const month = moment(recordDetails.date).format('MMM');

  const newRec = {
    id: uuidv4(),
    account_id: recordDetails.account_id,
    date: recordDetails.date,
    description: recordDetails.description,
    amount: recordDetails.result,
    type: recordDetails.type
  };

  update(year, month, newRec, records);

  return {
    type: ADD_NEW_RECORD,
    payload: records
  };
};

const update = (year, month, obj, target) => {
  [year, month].reduce((r, e, i, a) => {
    if (!a[i + 1] && r[e]) {
      r[e].records.push(obj);

      if (obj.type === 'expense') r[e].totalExpenses = parseFloat(r[e].totalExpenses) + parseFloat(obj.amount);
      if (obj.type === 'income') r[e].totalIncome = parseFloat(r[e].totalIncome) + parseFloat(obj.amount);
    }
    return r[e] = (r[e] || (a[i + 1] ? {} : {
      records: [obj],
      totalExpenses: obj.type === 'expense' ? parseFloat(obj.amount) : 0,
      totalIncome: obj.type === 'income' ? parseFloat(obj.amount) : 0,
      type: obj.type
    }));
  }, target);
};

And Reducer as below:

switch (action.type) {
  case ADD_NEW_RECORD:
    return { ...state, records: action.payload };

标签: javascriptreactjsreact-nativereduxstate

解决方案


this.props.addNewRecord({ 
  recordDetails: { ...this.props.recordDetails, type: this.state.type },
  records: _.cloneDeep(this.props.records)//this.props.records
});

问题是我已经通过this.props.recordsrecords,后来发生了变异,最终旧状态变异为与新状态相同,这就是 Redux 无法发现差异的原因。

感谢@Y.Gherbi 发现了这个缺陷。希望它可以帮助遇到同样问题的人


推荐阅读