question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Bug: setState does not rerender a functional component when an object's property is deleted

See original GitHub issue

React version: 16.13.1 and 16.12.0

Steps To Reproduce

  1. Create a state variable that contains an object. E.g.
const [employees, setEmployees] = useState({
    taimoor: {
      age: 21,
      occupation: "Web developer"
    },

    volod: {
      age: 22,
      occupation: "Programmer"
    },

    dawson: {
      age: 23,
      occupation: "Security analyst"
    },

    andrew: {
      age: 21,
      occupation: "HR"
    }
  });
  1. Add a function that will delete a property of that object using setState(...). E.g.
function delEmployee(name) {
    setEmployees(prev => {
      delete prev[name]; // The delete keyword does not trigger a rerender
      return prev;
    });

    console.log("State was updated!", employees); // Despite the state updating just fine!
  }
  1. To actually trigger the rerender that should happen, edit the state of some other variable. E.g. setTextBoxInput(...)

Link to code example: https://codesandbox.io/s/reverent-ganguly-3y19r?file=/src/App.js:471-1114

The code sample above also contains a workaround for the delete keyword not triggering a rerender, which is to use Object.assign({}, obj) and then use delete.

The current behavior

After using the delete keyword on the previous object within setState((prev) => {...}) the state is successfully updated, but a rerender does not occur. A workaround is to copy the object, then use the delete keyword.

The expected behavior

Using the delete keyword on the previous object within setState((prev) => {...}) should cause a rerender.

Issue Analytics

  • State:closed
  • Created 3 years ago
  • Comments:6

github_iconTop GitHub Comments

2reactions
vkurchatkincommented, Jun 23, 2020

React detects state changes by comparing old state with new state. If it is the same object it infers that no render is required

0reactions
bvaughncommented, Jun 23, 2020

This sandbox shows two problems:

  1. Treat a React state object as immutable. Read from it only. Don’t write.
  2. Return a new object (or value) if you want to update the component and re-render. React may choose to bail out in some cases if you return the previous state object because React does not do any deep cloning or comparison of the object. (That would expensive.)

You can clone the object and then delete the field- or just don’t clone that field in the first place, whichever is easier.

Read more comments on GitHub >

github_iconTop Results From Across the Web

functional component is not re-rendering after state change in ...
Your current initial state is an empty array, and you are trying to access pollOptions , which is a property that doesn't exist...
Read more >
When does React re-render components? - Felix Gerschau
In React hooks, the forceUpdate function isn't available. You can force an update without altering the components state with React.useState like ...
Read more >
Updating Arrays in State - React Docs
Just like with objects, when you want to update an array stored in state, you need to create a new one (or make...
Read more >
Using React useState with an object - LogRocket Blog
Learn how to use useState when working with objects by creating a temporary object and using object destructuring to create a new object....
Read more >
React Gotchas, Anti-Patterns, and Best Practices | by Steven Li
Because we are passing anonymous functions, React will always re-render since it receives a new anonymous function as a prop which it is...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found