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.

Inconsistent `setState` behavior between React and Preact (breaking react-select)

See original GitHub issue

I’m using react-select with Preact (+ Preact-compat) and the arrow to open the drop down is not working. This is because of the following code in React Select:

handleMouseDownOnArrow (event) {
	// if the event was triggered by a mousedown and not the primary
	// button, or if the component is disabled, ignore it.
	if (this.props.disabled || (event.type === 'mousedown' && event.button !== 0)) {
		return;
	}
	// If the menu isn't open, let the event bubble to the main handleMouseDown
	if (!this.state.isOpen) {
		this.setState({
			isOpen: true,
		});
	}
	// prevent default event handlers
	event.stopPropagation();
	event.preventDefault();
	// close the menu
	if(this.state.isOpen){
		this.closeMenu();
	}
}

When trying to open the select and in React, the this.setState({ isOpen: true}) call will change the state async, whereas in Preact this happens immediately. This means that, in React, the expression in the line if(this.state.isOpen){ will be false, but in Preact it’s true. So state.isOpen is flicked to true and then straight back to false before render() is called. Meaning that in Preact this code has no effect.

It looks like this can be fixed with a simple if/else (Unless there’s some deliberate reason those event.stop/prevent calls are sandwiched in there). But I thought this was worth sharing since I can imagine react-select is commonly used with Preact.

Is this subtle difference in behavior considered a Preact bug?

I guess it could also be fixed be proxying setState calls via setTimeout in Preact-compat. Happy to create a PR here.

Issue Analytics

  • State:closed
  • Created 6 years ago
  • Comments:12 (9 by maintainers)

github_iconTop GitHub Comments

1reaction
marvinhagemeistercommented, May 19, 2018

@philmander Thanks for the jsbin links! I just checked with the official react docs and they actively discourage relying on reading this.state right after a setState call. Instead they recommend using a callback function. For preact we encourage the same patterns, meaning it is always unsafe to rely on this.state immediately after setState.

The code currently found in master for react-select seems to have fixed this particular issue 🎉

0reactions
philmandercommented, Apr 23, 2018

Just revisiting this issue. I created a couple of demos to illustrate the difference in case its not clear:

Preact: http://jsbin.com/taroyax/edit?html,js,console,output React: http://jsbin.com/vozuguj/edit?html,js,console,output

Read more comments on GitHub >

github_iconTop Results From Across the Web

React JS setState behaviour - Stack Overflow
setState method just only call the enqueueSetState method. Which in his turn enqueue updating of particular react component.
Read more >
Differences to React - Preact
The main difference between Preact and React is that Preact does not implement a synthetic event system for size and performance reasons. Preact...
Read more >
Upgrading from Preact 8.x
This document is intended to guide you through upgrading an existing Preact 8.x application to Preact X and is divided in 3 main...
Read more >
Switching to Preact (from React)
Switch your imports to preact and remove incompatible code. Easy: `preact-compat` Alias. How to Alias preact-compat. Aliasing via Webpack; Aliasing ...
Read more >
sitemap-1.xml - LogRocket Blog
... https://blog.logrocket.com/how-typescript-breaks-referential-transparency- ... blog.logrocket.com/returning-null-from-setstate-in-react-16-5fdb1c35d457/ ...
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