1

I am new to React. I've been struggling for hours with this minor problem in such short and simple code. As far as I know, using useState, setSomething("foo"); should change something into "foo". However, for some reason, it seems it doesn't work without any warning or error.

What would be the reason and how can I solve it? Thanks!

This is my code:

import * as React from 'react';
import { useNavigate } from 'react-router-dom';
import { GET_RANDOM_NOTE_ID_API_RUL } from '../Constants/endpoints';

export default function useRandomNote() {
    const [randomNoteId, setRandomNoteId] = React.useState('');
    const navigate = useNavigate();

    React.useEffect(() => {
        fetch(`${process.env.REACT_APP_BACKEND_URL}/${GET_RANDOM_NOTE_ID_API_RUL}`)
            .then(response => response.json())
            .then(data => {

                console.log(data);
                console.log(`This is data.noteId: ${data.noteId}`);
                setRandomNoteId(data.noteId); // <- Doesn't work!!!
                console.log(`This is randomNoteId: ${randomNoteId}`);

            })
            .then(() => {
                navigate(`../notes/${randomNoteId}`);
            });
    }, [])

}

Console:

{noteId: 305}
This is data.noteId: 305
This is randomNoteId: 

Everything else here works well except setRandomNoteId(data.noteId), There is no warning or error at all. But even though I used setRandomNoteId, randomNoteId does NOT change from '' to whatever. It seems very strange.

The next lines of code after "setRandomNoteId(data.noteId);", like "console.log(This is randomNoteId: ${randomNoteId});" and "navigate(../notes/${randomNoteId});", work perfectly fine.

Why would this happen, and what would be the solution?

2 Answers2

0

You cannot do that because react will update state after next render

React buffer all state changes

The solution is you need to store it in temporary variable

console.log(data);

const noteId = data.noteId

console.log(`This is data.noteId: ${data.noteId}`);
setRandomNoteId(noteId);
console.log(`This is randomNoteId: ${noteId}`);

Or you can use flushSync

console.log(data);
console.log(`This is data.noteId: ${data.noteId}`);

flushSync(() => {
  setRandomNoteId(data.noteId);
});

console.log(`This is randomNoteId: ${randomNoteId}`);
kennarddh
  • 2,186
  • 2
  • 6
  • 21
0

In a fuction, out of useEffect without dep. array after setState you can not see the change. It must re-runs to see changes. So for testing purpose, can you try this;

React.useEffect(() => {
        console.log(randomNoteId);
}, [randomNoteId]);

On every change at randomNoteId, it will console log the value, so you can check is it really changed or not changed.