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

Bug: Breaking change of use-subscription from 1.6.0 to 1.7.0 #24508

Closed
Jack-Works opened this issue May 6, 2022 · 5 comments
Closed

Bug: Breaking change of use-subscription from 1.6.0 to 1.7.0 #24508

Jack-Works opened this issue May 6, 2022 · 5 comments
Labels
Status: Unconfirmed A potential issue that we haven't yet confirmed as a bug

Comments

@Jack-Works
Copy link
Contributor

React version: 18.1.0

It looks like use-subscription has changed the internal implementation to useSyncExternalStore.

It is causing the following error in our application:

Warning: The result of getSnapshot should be cached to avoid an infinite loop

Uncaught Error: Maximum update depth exceeded. This can happen when a component repeatedly calls setState inside componentWillUpdate or componentDidUpdate. React limits the number of nested updates to prevent infinite loops.

React should bump the major version for use-subscription instead of the minor version!

@Jack-Works Jack-Works added the Status: Unconfirmed A potential issue that we haven't yet confirmed as a bug label May 6, 2022
@gaearon
Copy link
Collaborator

gaearon commented May 9, 2022

Oops, that's our bad. We haven't considered this change in behavior.

Since it's already been out for a few weeks, it seems like changing the behavior again risks being more disruptive. So for now we're going to leave this as is and see if we get more complaints.

Sorry!

@gaearon gaearon closed this as completed May 9, 2022
@reggaebass
Copy link

I am encountering this same error. Is there a resolution?

@RemLawrence
Copy link

Any update on this?

@grctest
Copy link

grctest commented Oct 27, 2023

Would appreciate a fix for using nanostore queries in react, much appreciated :)

@lucasbasquerotto
Copy link

lucasbasquerotto commented Oct 27, 2023

For now I'm verifying if the properties values remain unchanged. For example, to get the window dimensions:

export interface WindowSizes {
	width: number;
	height: number;
}

const getSnapshot = ((value: WindowSizes | undefined) => () => {
	if (
		!value ||
		value.width !== window.innerWidth ||
		value.height !== window.innerHeight
	) {
		value = { width: window.innerWidth, height: window.innerHeight };
	}

	return value;
})(undefined);

const initialSizes: WindowSizes = {
	width: 0,
	height: 0,
};

const getServerSnapshot = () => initialSizes;

const subscribe = (
	callback: (this: Window, ev: WindowEventMap['resize']) => unknown,
) => {
	window.addEventListener('resize', callback);
	return () => window.removeEventListener('resize', callback);
};

export const useWindowDimensions = () => {
	// the 3rd parameter is optional and only needed for server side rendering
	return useSyncExternalStore(subscribe, getSnapshot, getServerSnapshot);
};

The getSnapshot function verifies if the value changed instead of returning a new object each time.

For more complex objects, a deepEqual comparison may be better (instead of comparing each property individually).

Not the ideal scenario, but for now this is what solved this issue for me.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Status: Unconfirmed A potential issue that we haven't yet confirmed as a bug
Projects
None yet
Development

No branches or pull requests

7 participants
@gaearon @Jack-Works @reggaebass @grctest @lucasbasquerotto @RemLawrence and others