我试图将值从API传递到state,但总是给出这个错误。
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
}
});
这修复了前三个子弹。关于减速器,如果你这样写可能更有意义,但它也做同样的事情。
[getListNamesDictionary.fulfilled]: (state, action) => {
namesAdapter.upsertMany(state, action)
}
最后一个要点是您发布的特定错误消息的原因:
TypeError:无法读取未定义的属性"id">
实际上看起来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