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.

[Updates] Bailing out of a transactional setState call

See original GitHub issue

For practical reasons about performance and energy conservation (in this sense, all React components are non-idempotent and have side effects), I occasionally will check my state before setting it:

if (this.state.something) {
  this.setState({ ... });
}

I would like to be able to do this with the transactional version of setState as well:

this.setState(state => {
  if (state.something) {
    return { ... };
  }
  // if null or undefined (or false?) is returned, don't re-render!
});

A toy example of this is a piece of component state that gets updated during each scroll event. Due to event batching (especially with RN), multiple scroll events can fly in during the same batch.

<ScrollView onScroll={() => {
  this.setState(state => {
    if (state.numberOfScrollEvents < 10) {
      return { numberOfScrollEvents: state.numberOfScrollEvents + 1 };
    }
  });
} />

Issue Analytics

  • State:closed
  • Created 8 years ago
  • Comments:10 (5 by maintainers)

github_iconTop GitHub Comments

4reactions
gaearoncommented, Oct 3, 2017

We allow returning null from updaters to prevent an update in 16.

0reactions
idecommented, Oct 1, 2015

Re: the mutable values – the code doesn’t rely on deep updates. I meant something like this:

constructor() {
  this.state = { model: null, /* other fields */ };
}
onDataStoreUpdate(model) {
  // model could be a mutable object that the data store mutates when
  // the model's data changes. The store still calls `onDataStoreUpdate`
  // and we call `setState`, so there's no relying on `forceUpdate`
  this.setState({ model });
}
render() {
  // Is the re-rendering of Subcomponent what you consider a "deep update for
  // state consistency"?
  return <Subcomponent model={model} />;
}
shouldComponentUpdate(nextProps, nextState) {
  // Cannot reliably tell if nextState.model changed since it's mutable
}

you will always get a new props object if your parent rerendered.

This is pretty helpful to know I can rely on that. In my actual use case this helps a lot. I do still want to be able to use this.setState(this.state) to signal that there should be no update (what you’re doing here: https://github.com/reactjs/react-future/blob/master/09 - Reduce State/01 - Declarative Component Module.js#L41). It is pretty convenient.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Why React needs another render to bail out state updates?
Internally useState is a useReducer, with a basicReducer, The hooks uses a queue of changes in order to update the states.
Read more >
Understanding React.js (Part 2) - Batched Updates
React implements a batched updating mechanism for several scenarios, such as changing states via setState() within life cycles, re-rendering ...
Read more >
CHANGELOG.md - facebook/react - Sourcegraph
No warning about setState on unmounted components: Previously, React warned about memory leaks when you call setState on an unmounted component.
Read more >
React doesn't always trigger a re-render on setState
Bailing out of a state update​​ If you update a State Hook to the same value as the current state, React will bail...
Read more >
com.fulcrologic.fulcro.components — com.fulcrologic/fulcro 3.5.2
NOTE: This is at compile time, so the get-query calls are still embedded (thus cannot use the AST) ... This also compress the...
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