![](/img/trans.png)
[英]React & Redux, Update state, Error: A state mutation was detected between dispatches
[英]A state mutation was detected between dispatches, Redux toolkit and selectors/reselect
我在createSelector
和 async thunk 方面遇到了一些麻煩。
基本上我試圖檢索鏈接列表,並根據點擊次數從高到低對它們進行排序。
這是我的簡化代碼。
主頁.tsx
export const MainPage = (): JSX.Element => {
const dispatch = useDispatch();
const allLinks = useSelector(selectLinks);
useEffect(() => {
dispatch(getLinks());
}, [dispatch]);
return (
<div>
{allLinks.map((link) => ()} //unrelated logic
</div>
);
};
鏈接.actions.ts
export const getLinks = createAsyncThunk(
"getLinks",
async () => {
const links = await axios.get"/links")
return links;
},
);
鏈接.slice.ts
const linksSlice = createSlice({
name: "data",
initialState,
reducers: {},
extraReducers: (builder) => {
builder
.addCase(
getLinks.fulfilled,
(state, action) => {
state.links = action.payload;
},
);
},
});
鏈接選擇器.ts
const selectLinksState = (state: RootState) => state.links;
export const selectLinks = createSelector(selectLinksState, (state) =>
state.links.sort((a, b) => b.clickCount - a.clickCount),
);
所以這個編譯很好,但是當我在 web 瀏覽器中打開它時,我收到以下錯誤Error: Invariant failed: A state mutation was detected between dispatches
有誰知道我做錯了什么? 我很確定這與選擇器有關,因為如果我在操作中獲取鏈接后直接對鏈接進行排序,它就可以正常工作。
因此,即使 Redux 工具包是可變的,我還是修改了重新選擇 function 並將其更改為:
export const selectLinks = createSelector(selectLinksState, (state) => {
const sortedArray = [...state.links].sort(
(a, b) => b.clickCount - a.clickCount,
);
return sortedArray;
});
我的邏輯是創建一個新數組,這樣它就不會引起任何突變問題。 現在工作正常!
Sort 使用就地排序算法,它不返回新數組,因此您正在通過選擇器邏輯對 state 進行變異。
sort()
方法對數組的元素進行就地排序並返回排序后的數組。 默認排序順序是升序,建立在將元素轉換為字符串,然后比較它們的 UTF-16 代碼單元值序列的基礎上。
您可以使用.slice
in-line 創建links
數組的副本,然后對新數組引用進行排序:
export const selectLinks = createSelector(
[selectLinksState],
(state) => state.links.slice().sort((a, b) => b.clickCount - a.clickCount),
);
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.