javascript - 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 };
解决方案
this.props.addNewRecord({
recordDetails: { ...this.props.recordDetails, type: this.state.type },
records: _.cloneDeep(this.props.records)//this.props.records
});
问题是我已经通过this.props.records
了records
,后来发生了变异,最终旧状态变异为与新状态相同,这就是 Redux 无法发现差异的原因。
感谢@Y.Gherbi 发现了这个缺陷。希望它可以帮助遇到同样问题的人
推荐阅读
- php - Laravel 6,mysqldump 问题
- javascript - html2canvas v1.0.0 rc 5 不适用于 ios
- php - 按php中的最大和最小变量对数据进行排序?
- jquery - 如何将值从 jquery 传递到 Spring Controller 并返回 List?
- java - 无法在 Mac 上安装 Ecpise:Java 运行时环境 (JRE) 或 Java 开发工具包 (JDK) 必须可用才能运行 Eclipse
- regex - 我将如何复制一行并更改复制行内的一段文本?
- python-3.x - 如何使用定义的函数正确创建嵌套的 for 循环以生成值数组
- javascript - Slick Slider 2 滑块与 Bootstrap Modal 中的幻灯片和 Slider 不匹配
- javascript - setInterval 不使用变量更新
- reactjs - React 组件不会发生 onChange 事件