React&Reselect选择器声称更新后状态相同
React & Reselect selector claims state is the same after update
我正在我的项目中实施 Reselect,但对如何正确使用它有些困惑。在学习了关于如何使用 reselect 的多篇教程和文章之后,我使用了相同的模式,但仍然有些地方没有按预期工作。
我的选择器:
const getBaseInfo = (state) => state.Info;
const getResources = (state) => state.Resources;
export const ASelector = createSelector(
[getBaseInfo, getResources],
(items, resources) => {
let result = {};
for(const item in items) {
console.log(item);
result[item] = _.pick(items[item], ['Title', 'Type', 'Beginning', 'minAmount', 'Address'])
}
for(const item in resources) {
console.log(item);
result[item] = {...result[item], firstImage: resources[item].firstImage}
}
return result;
}
);
mapStateToProps 组件:
function mapStateToProps(state) {
console.log(state);
return {
gridInfo: ASelector(state)
}
}
现在一开始我的初始状态是:
state = { Info: {}, Resources: {} }
我的减速器:
const Info = ArrayToDictionary.Info(action.payload.data.Info);
const Resources = ArrayToDictionary.Resources(action.payload.data.Info);
let resourcesKeys = Object.keys(Resources);
let infoKeys = Object.keys(Info);
let temp = { ...state };
let newInfo;
for (let item of infoKeys) {
newInfo = {
Title: Info[item].Title,
Type: Info[item].Type,
BeginningOfInvesting: Info[item].BeginningOfInvesting,
DateOfEstablishment: Info[item].DateOfEstablishment,
pricePerUnit: Info[item].PricePerUnit,
minUnits: Info[item].MinUnits,
publicAmount: Info[item].PublicAmount,
minInvestmentAmount: Info[item].MinInvestmentAmount,
EinNumber: Info[item].EinNumber,
Address: Info[item].Address,
Status: Info[item].Status,
Lat: Info[item].Lat,
Lng: Info[item].Lng,
CurrencySymbol: Info[item].CurrencySymbol,
Publicity: Info[item].Publicity
}
temp.Info[item] = { ...temp.Info[item], ...newInfo }
}
for (let item of resourcesKeys) {
temp.Resources[item] = { ...temp.Resources[item], ...Resources[item] }
}
return temp;
当组件以初始状态呈现时,我有一个操作从 api 中提取数据并将其相应地保存到 reducer 中的状态中。
现在我的状态变了,但是稍微调试了一下reselects的代码,在比较函数中发现新旧状态是一样的。
突然间,我的 "old" 状态已经填充了 newState 数据,并且当它们变得相同时,它当然无法比较。
我的选择器有问题吗?
我确实尝试按照文档中的说明使用它,但仍然无法理解如何解决我的小问题。
非常感谢您的阅读和帮助!
看起来 temp.Info[item]
和 temp.Resources[item]
行正在改变现有状态。您制作了顶层的浅表副本,但没有正确复制第二层。请参阅 Redux 文档中的 Immutable Update Patterns 页面,了解为什么这是一个问题以及应该怎么做。
您可能想尝试使用 immer
library to simplify your immutable update logic. Also, our new redux-starter-kit
库在内部使用 Immer。
我正在我的项目中实施 Reselect,但对如何正确使用它有些困惑。在学习了关于如何使用 reselect 的多篇教程和文章之后,我使用了相同的模式,但仍然有些地方没有按预期工作。
我的选择器:
const getBaseInfo = (state) => state.Info;
const getResources = (state) => state.Resources;
export const ASelector = createSelector(
[getBaseInfo, getResources],
(items, resources) => {
let result = {};
for(const item in items) {
console.log(item);
result[item] = _.pick(items[item], ['Title', 'Type', 'Beginning', 'minAmount', 'Address'])
}
for(const item in resources) {
console.log(item);
result[item] = {...result[item], firstImage: resources[item].firstImage}
}
return result;
}
);
mapStateToProps 组件:
function mapStateToProps(state) {
console.log(state);
return {
gridInfo: ASelector(state)
}
}
现在一开始我的初始状态是:
state = { Info: {}, Resources: {} }
我的减速器:
const Info = ArrayToDictionary.Info(action.payload.data.Info);
const Resources = ArrayToDictionary.Resources(action.payload.data.Info);
let resourcesKeys = Object.keys(Resources);
let infoKeys = Object.keys(Info);
let temp = { ...state };
let newInfo;
for (let item of infoKeys) {
newInfo = {
Title: Info[item].Title,
Type: Info[item].Type,
BeginningOfInvesting: Info[item].BeginningOfInvesting,
DateOfEstablishment: Info[item].DateOfEstablishment,
pricePerUnit: Info[item].PricePerUnit,
minUnits: Info[item].MinUnits,
publicAmount: Info[item].PublicAmount,
minInvestmentAmount: Info[item].MinInvestmentAmount,
EinNumber: Info[item].EinNumber,
Address: Info[item].Address,
Status: Info[item].Status,
Lat: Info[item].Lat,
Lng: Info[item].Lng,
CurrencySymbol: Info[item].CurrencySymbol,
Publicity: Info[item].Publicity
}
temp.Info[item] = { ...temp.Info[item], ...newInfo }
}
for (let item of resourcesKeys) {
temp.Resources[item] = { ...temp.Resources[item], ...Resources[item] }
}
return temp;
当组件以初始状态呈现时,我有一个操作从 api 中提取数据并将其相应地保存到 reducer 中的状态中。
现在我的状态变了,但是稍微调试了一下reselects的代码,在比较函数中发现新旧状态是一样的。 突然间,我的 "old" 状态已经填充了 newState 数据,并且当它们变得相同时,它当然无法比较。
我的选择器有问题吗?
我确实尝试按照文档中的说明使用它,但仍然无法理解如何解决我的小问题。
非常感谢您的阅读和帮助!
看起来 temp.Info[item]
和 temp.Resources[item]
行正在改变现有状态。您制作了顶层的浅表副本,但没有正确复制第二层。请参阅 Redux 文档中的 Immutable Update Patterns 页面,了解为什么这是一个问题以及应该怎么做。
您可能想尝试使用 immer
library to simplify your immutable update logic. Also, our new redux-starter-kit
库在内部使用 Immer。