I am using react-redux
to store a state modeData
which is an array of objects. Using react-hotkeys-hook
, when the user presses ctrl l
, a function runs which updates the state. In that same function, when I console.log
the same state, it does not reflect the changes.
Here's the code I'm using:
import { useSelector, useDispatch } from "react-redux";
import { modeDataIncrement } from "./redux/modeSlice";
import { useHotkeys } from "react-hotkeys-hook";
import { useEffect } from "react";
//..
const modeData = useSelector((state) => state.mode.modeData); //array of objects.
const handler = (id) => {
const isActive = modeData.find((x) => x.id === id).active;
console.log(modeData); // does not show the updated state
dispatch(modeDataIncrement(id));
};
useHotkeys("ctrl l", () => handler("Clone"));
useEffect(() => {
console.log(modeData); //working fine!
}, [modeData]);
modeSlice.js
:
import { createSlice } from "@reduxjs/toolkit";
export const modeSlice = createSlice({
name: "mode",
initialState: {
modeData: [{ id: "Clone", active: false }],
},
reducers: {
modeDataIncrement: (state, action) => {
state.modeData.find(
(e) => e.id === action.payload && (e.active = !e.active)
);
},
},
});
export const { modeDataIncrement } = modeSlice.actions;
export default modeSlice.reducer;
Any thoughts on what I'm doing wrong?
Thanks!
CodePudding user response:
Your code needs to use the latest version of modeData, but based on the source code of useHotkeys, it will memoize the function, and not update it automatically. So you're always using the version of the callback that existed on the first render.
To fix this, you need to pass a dependency array in to useHotkeys, so it can break the memoization:
const handler = (id) => {
const isActive = modeData.find((x) => x.id === id).active;
console.log(modeData);
dispatch(modeDataIncrement(id));
};
useHotkeys("ctrl l", () => handler("Clone"), [modeData]);