facebook / react

The library for web and native user interfaces.
https://react.dev
MIT License
229.3k stars 46.96k forks source link

Bug: Components don't re-render after changing state #21148

Closed ghost closed 3 years ago

ghost commented 3 years ago

https://github.com/facebook/react/issues/19181 is pretty much my issue, but I did not find any useful information there. I tried to fix it by assigning the prevState to another variable and then editing the new one, but it did not work

React version: 17.0.2

Steps To Reproduce

Use this code:

import { useState } from "react";
import "./styles.css";

//use this style css or tailwind:
//.hidden {
//  display: none;
//}

//.block {
//  display: block;
//}

export default function App() {
  const [menus, setMenus] = useState({
    gui: {
      name: "gui",
      state: "block",
      visible: "block"
    }
  });

  const toggle = (element) => {
    var object;
    if (element.state === element.visible) {
      setMenus((prevMenus) => {
        object = prevMenus;
        object[element.name].state = "hidden";
        return object;
      });
    } else if (element.state === "hidden") {
      setMenus((prevMenus) => {
        object = prevMenus;
        object[element.name].state = element.visible;
        return object;
      });
    }
    console.log("Toggle called!");
  };

  return (
    <div className="App">
      <h1 className={menus.gui.state}>Hi!</h1>
      <button onClick={() => toggle(menus.gui)}>Click me to toggle Hi!</button>
    </div>
  );
}

Link to code example:

https://codesandbox.io/s/stoic-mahavira-gp5wf?fontsize=14&hidenavigation=1&theme=dark

The current behavior

The h1 with "Hi!" does not re-render, even though I am creating a new object

The expected behavior

The h1 with "Hi!" should re-render every time toggle is called

vkatatab commented 3 years ago

You are not creating a new object, when you do object = prevMenus they are still the same You could try to deep cloning your object with (or something like it): object = JSON.parse(JSON.stringify(prevMenus))

eps1lon commented 3 years ago

The answer of @vkatatab is correct. Closing since the described behavior is expected.