3

I have this component using Hooks:

function App() {
  const [text, setText] = useState({ h1: "hello", h2: "hi" });

  const changeH1 = () => {
    setText({
      ...text,
      h1: text.h1 + "C"
    });
  };

  const changeH2 = () => {
    setText({
      ...text,
      h2: text.h2 + "X"
    });
  };

  const changeAll = () => {
    changeH1();
    changeH2();
  };

  return (
    <div className="App">
      <h1 onClick={() => changeH1()}>{text.h1}</h1>
      <h1 onClick={() => changeH2()}>{text.h2}</h1>
      <button onClick={() => changeAll()}>Change</button>
    </div>
  );
}

It will display two headings with some text and a button. When I click on the first heading, the "C" character will be added to the heading. When I click on the second heading, the "X" character will be added to the heading. When I click the button, it will do two actions above at the same time.

It works fine on two headings but the button. When I click the button, only the second heading changes. I think that the setText of changeH1 and changeH2 are not working when they are called in changeAll. What's wrong with my code?

1
  • 2
    <button onClick={() => changeAll}>Change</button> try to replace changeAll by changeAll() Commented Apr 6, 2019 at 8:49

1 Answer 1

1

Because changeH2() overwrites h1 property by doing ...text.

The 2 setText() calls are executed before a re-render - I believe it's due to batching as explained in https://overreacted.io/react-as-a-ui-runtime/#batching

A solution would be to use a simple state instead of an object:

  const [h1, setH1] = useState("hello");
  const [h2, setH2] = useState("hi");
  ...

Or else useReducer for more complex operations https://reactjs.org/docs/hooks-reference.html#usereducer

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.