使用 reduxjs/toolkit 时无法读取未定义的 属性 'ids'
Cannot read property 'ids' of undefined when use reduxjs/toolkit
我正在尝试将值从 API 传递到状态,但总是出现此错误。
TypeError: 无法读取未定义的 属性 'ids'
selectIds
我正在使用 'reduxjs/toolkit' 我尝试了所有方法但仍然继续出现该错误 你能帮帮我吗
这是来自 Slic 文件的代码
export const getListNamesDictionary = createAsyncThunk('dictionary/names/getNames', async () => {
try {
const response = await axios.get('http://localhost:6005/api/lookup/list-name');
const data = await response.data;
// dispatch(getNames(data));
debugger;
console.log(data);
return data;
} catch (error) {
return console.error(error.message);
}
});
const namesAdapter = createEntityAdapter({});
和 Slic :
const namesDictionarySlice = createSlice({
name: 'names',
initialState: {
names: []
},
reducers: {
},
extractors: {
[getListNamesDictionary.fulfilled]: (state, action) => {
state.entities.push(action.payload);
}
}
});
export const { selectAll: selectNamesDictionary } = namesAdapter.getSelectors(state => state.data);
此代码来自我需要分派操作的组件
const names = useSelector(selectNamesDictionary);
useEffect(() => {
// dispatch(getListNamesDictionary()).then(() => setLoading(false));
dispatch(getListNamesDictionary()).then(() => setLoading(false));
}, [dispatch]);
有没有提示为什么会出现该错误?谢谢
您没有正确使用实体适配器。它期望以以下形式管理状态:
{
ids: [1, 2],
entities: {
1: {/*...*/},
2: {/*...*/}
}
}
您的 names
切片与该形状不匹配。但这是一个简单的修复,因为 namesAdapter
提供了所有需要的工具。要修复的错误的简要说明:
- 属性 名字
extractors
应该是 extraReducers
state.entities.push
需要换成适配器函数
initialState
需要属性 ids
和 entities
- 选择器需要定位正确的位置
const namesAdapter = createEntityAdapter({});
const namesDictionarySlice = createSlice({
name: "names",
initialState: namesAdapter.getInitialState(),
reducers: {},
extraReducers: {
[getListNamesDictionary.fulfilled]: namesAdapter.upsertMany
}
});
这修复了前三个项目符号。关于reducer,这样写可能更有意义,但它的作用是一样的。
[getListNamesDictionary.fulfilled]: (state, action) => {
namesAdapter.upsertMany(state, action)
}
最后一个要点是您发布的特定错误消息的原因:
TypeError: Cannot read property 'ids' of undefined
实际上 state.data
好像是 undefined
。这个namesDictionarySlice
是用来控制你根状态的data
属性吗?如果它是其他东西,比如 state.names
,那么您需要将选择器更改为 namesAdapter.getSelectors(state => state.names)
。
如果您的商店是这样的:
const store = configureStore({
reducer: {
names: namesReducer
}
});
你会想要:
export const { selectAll: selectNamesDictionary } = namesAdapter.getSelectors(
(state) => state.names // select the entity adapter data from the root state
);
在Slic函数中,我写错了,我最多写'extraReducer'但我写了“提取器”:D
我正在尝试将值从 API 传递到状态,但总是出现此错误。
TypeError: 无法读取未定义的 属性 'ids' selectIds
我正在使用 'reduxjs/toolkit' 我尝试了所有方法但仍然继续出现该错误 你能帮帮我吗
这是来自 Slic 文件的代码
export const getListNamesDictionary = createAsyncThunk('dictionary/names/getNames', async () => {
try {
const response = await axios.get('http://localhost:6005/api/lookup/list-name');
const data = await response.data;
// dispatch(getNames(data));
debugger;
console.log(data);
return data;
} catch (error) {
return console.error(error.message);
}
});
const namesAdapter = createEntityAdapter({});
和 Slic :
const namesDictionarySlice = createSlice({
name: 'names',
initialState: {
names: []
},
reducers: {
},
extractors: {
[getListNamesDictionary.fulfilled]: (state, action) => {
state.entities.push(action.payload);
}
}
});
export const { selectAll: selectNamesDictionary } = namesAdapter.getSelectors(state => state.data);
此代码来自我需要分派操作的组件
const names = useSelector(selectNamesDictionary);
useEffect(() => {
// dispatch(getListNamesDictionary()).then(() => setLoading(false));
dispatch(getListNamesDictionary()).then(() => setLoading(false));
}, [dispatch]);
有没有提示为什么会出现该错误?谢谢
您没有正确使用实体适配器。它期望以以下形式管理状态:
{
ids: [1, 2],
entities: {
1: {/*...*/},
2: {/*...*/}
}
}
您的 names
切片与该形状不匹配。但这是一个简单的修复,因为 namesAdapter
提供了所有需要的工具。要修复的错误的简要说明:
- 属性 名字
extractors
应该是extraReducers
state.entities.push
需要换成适配器函数initialState
需要属性ids
和entities
- 选择器需要定位正确的位置
const namesAdapter = createEntityAdapter({});
const namesDictionarySlice = createSlice({
name: "names",
initialState: namesAdapter.getInitialState(),
reducers: {},
extraReducers: {
[getListNamesDictionary.fulfilled]: namesAdapter.upsertMany
}
});
这修复了前三个项目符号。关于reducer,这样写可能更有意义,但它的作用是一样的。
[getListNamesDictionary.fulfilled]: (state, action) => {
namesAdapter.upsertMany(state, action)
}
最后一个要点是您发布的特定错误消息的原因:
TypeError: Cannot read property 'ids' of undefined
实际上 state.data
好像是 undefined
。这个namesDictionarySlice
是用来控制你根状态的data
属性吗?如果它是其他东西,比如 state.names
,那么您需要将选择器更改为 namesAdapter.getSelectors(state => state.names)
。
如果您的商店是这样的:
const store = configureStore({
reducer: {
names: namesReducer
}
});
你会想要:
export const { selectAll: selectNamesDictionary } = namesAdapter.getSelectors(
(state) => state.names // select the entity adapter data from the root state
);
在Slic函数中,我写错了,我最多写'extraReducer'但我写了“提取器”:D