0

I have a reducer in my useMessages() hook. For simplicity, let's focus on the "add" action of my reducer, which just adds a message to an array of messages and assigns an incrementing ID to it:

import { useReducer, useRef } from "react";

const useMessages = () => {
    const localMessageId = useRef(1);

    const [messages, dispatchMessages] = useReducer(
        (messages, action) => {
            switch (action.type) {
                case "add":
                    return [
                        ...messages,
                        {
                            ...action.message,
                            id: action.message.id ?? localMessageId.current++,
                        },
                    ];
                // Other actions
            }
        },
        []
    );

    return [messages, dispatchMessages, localMessageId.current];
};

export default useMessages;

The problem is that in Strict Mode, my ID is incremented twice, so the first message gets the ID of 2. I need to use the newly created ID after adding the message, but I'm not sure how to get this ID.

Is updating a useRef() value in a reducer even considered valid in React? I know that we're not supposed to run side effects in reducers, memo etc.

Robo Robok
  • 21,132
  • 17
  • 68
  • 126
  • 1
    Just store the counter in the reducer state. – Bergi Jun 11 '23 at 16:42
  • @Bergi I haven't thought about that, trying now. – Robo Robok Jun 11 '23 at 16:45
  • @Bergi okay, so it works, but there's still another problem about it. I need to use the newly created value in there, immediately after dispatching the `"add"` action. It's a WebSocket app and I need to send the message with the new ID. I sometimes lose track of how to do these things with hooks properly. – Robo Robok Jun 11 '23 at 17:19
  • Where is the code that sends the ws message? Is it happening in the reducer, in the action builder, in a middleware? – Bergi Jun 11 '23 at 17:21
  • @Bergi nowhere of these, it's just an event handler. I'm gonna update the question. – Robo Robok Jun 11 '23 at 17:24
  • Then probably just use the ref in there – Bergi Jun 11 '23 at 17:27
  • @Bergi I changed it to use `useRef()` there and I increment it inside the `"add"` action. I return the ref (not the value) from my hook, but when I use it after dispatching the action, it still has the old value. I remember reading about it a while ago in the context of `useMemo()` and it's apparently an expected behavior. Still not sure how to properly keep tract of the last ID of my `useReducer()` though. – Robo Robok Jun 11 '23 at 17:45
  • @Bergi I tried to ask ChatGPT, but it insists that it would change, but it does not. – Robo Robok Jun 11 '23 at 18:06
  • @Bergi I posted another question to describe the problem there: https://stackoverflow.com/questions/76451936/why-do-i-get-old-useref-value – Robo Robok Jun 11 '23 at 18:25

0 Answers0