0

As title. I try to set component state from child through callback given by parent. Demo is in https://codepen.io/jadecubes/pen/wvYxKEL

The callback looks like

A = () => {
    const [info, setInfo] = useState(["Hello world."]);

    return (
        <>
            <B
                onChange={() => {/*I am callback*/
                    info.length = 0;
                    info.push("Hey!");
                    setInfo(info);
                }}
            />
            <h1>{info}</h1>
        </>
    );
};

Clicking button doesn't change the text. But if it's something like below, it changes normally.

A = () => {
    const [info, setInfo] = useState(["Hello world."]);

    return (
        <>
            <B
                onChange={() => {/*I am callback*/
                    setInfo(['hey']);
                }}
            />
            <h1>{info}</h1>
        </>
    );
};

Any suggestions are welcome.

Yu Fang
  • 520
  • 5
  • 17
  • 1
    inside B i changed as you are setting length to 0 and adding new to setInfo , i changed setInfo(info); -> setInfo([...info]); it displays "hey" now when i click button in component A . Let me know if this is what you looking for so i can post as answer :) – ksd030687d May 14 '23 at 06:50

2 Answers2

1

You can't push items in the array that is stored in react state with push method because arrays store in react state are immutable. Here is the updated code. Try that:-

const { useState, useEffect } = React;

A = () => {
    const [info, setInfo] = useState(["Hello world."]);

    return (
        <>
            <B
                onChange={() => {
                    setInfo([
                      ...info,
                      "Hey!"
                    ]);
                }}
            />
            <h1>{info}</h1>
        </>
    );
};

B = (props) => {
    return (
        <>
            <button
                type="button"
                onClick={() => {
                    props.onChange();
                }}
            >
                Click Me!
            </button>
        </>
    );
};

const root = ReactDOM.createRoot(document.querySelector("#root"));
root.render(<A />);

You can read how to update arrays more in details in react docs.

Hope it will be helpful.

Developer
  • 1,297
  • 1
  • 4
  • 15
1

React state are immutable.

You should not aim to mutate the state directly by calling methods like push, pop

You should use methods that return new arrays like concat, …etc

Check React documentations below:

https://react.dev/learn/updating-arrays-in-state