Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Combine multiple state updates into a single operation to reduce renders #1251

Closed
JonathanCoxLRS opened this issue Jun 20, 2023 · 2 comments
Closed

Comments

@JonathanCoxLRS
Copy link

Example: I have 2 state properties as shown below.

const [a, setA] = useState(config.a ? config.a : null);
const [b, setB] = useState(config.b ? config.b : null);

Calling either setA or setB initiates a render.

As part of my app logic, there are situations in which both a and b need to be updated. However, rendering twice is undesirable as it results in visual flicker. Does the core library provide a way to combine those updates such that only one render is required?

I suppose I can rewrite my code to have a single properties property like this:

const [properties, setProperties] = useState(
	Object.freeze(
		{
			a: config.a ? config.a : null,
			b: config.b ? config.b : null
		}
	)
);

Then, I can update multiple properties like this:

setProperties(
	Object.freeze(
		Object.assign(
			{
				a: 1,
				b: 2
			},
			properties
		)
	)
);

What's the best practice to accomplish this? I'd rather use features of the core library than write my own workarounds for the state system.

Thanks!

@SBoudrias
Copy link
Owner

Hi! Thanks for bringing that feedback

I want to batch renders to handles cases like what you outlined. I didn't have time yet to implement, but it's definitively an update the would make sense.

The code is over here if you want to give it a try. The tests should catch any regression you'd introduce (I think they're end-to-end enough to not bulk on delayed re-renders; but might need to review that too.)

@SBoudrias
Copy link
Owner

Implemented a naïve version of this.

So on any sync functions, the state updates will be merged (See code at 165d6d8)

But it won't work if calling multiple times setState from within an async callback (like setTimeout.) Handling those would require to have asynchronous rendering loops, and that makes everything more complicated (testing, but also just things like making sure there's no delays when typing.) Since updating multiple states from async functions are not a pattern I've encountered often creating prompts, I'm leaning on the side of simplicity for now.

(And the code demo using an object state is a good work around for custom prompt requiring multi state updates from an async callback.)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants