Home > Software design >  State update not reflecting in custom hook
State update not reflecting in custom hook

Time:10-31

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]);
  • Related