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

WARNING - Detected multiple renderers concurrently rendering the same context provider (React 18.0.0?) #5243

Closed
DB-Alex opened this issue Apr 20, 2022 · 20 comments
Labels
Library: React InstantSearch < 7 Issues in any of the react-instantsearch@6 packages Library: React InstantSearch ≥ 7 Issues in any of the react-instantsearch@7 packages (formerly named react-instantsearch-hooks) Resolution: Wontfix

Comments

@DB-Alex
Copy link

DB-Alex commented Apr 20, 2022

🐛 Bug description

I get the following warning on the server side in react when i use:

import { findResultsState } from 'react-instantsearch-dom/server';

Warning: Detected multiple renderers concurrently rendering the same context provider. This is currently unsupported.
at Index (node_modules/react-instantsearch-core/dist/cjs/widgets/Index.js:86:34)
at IndexWrapper (node_modules/react-instantsearch-core/dist/cjs/widgets/Index.js:157:31)

Modules in package.json:

"react": "^18.0.0",
"react-dom": "^18.0.0",
"algoliasearch": "^4.13.0",
"react-instantsearch-dom": "^6.23.3",

@francoischalifour
Copy link
Member

Can you please reproduce the behavior in this React InstantSearch Server sandbox?

@DB-Alex
Copy link
Author

DB-Alex commented Apr 21, 2022

That would be very much work...

@DB-Alex
Copy link
Author

DB-Alex commented Apr 21, 2022

Warning: Detected multiple renderers concurrently rendering the same context provider. This is currently unsupported.
    at InstantSearch (/node_modules/react-instantsearch-core/dist/cjs/widgets/InstantSearch.js:101:34)
    at MainIndex (webpack-internal:///(api)/./src/components/organisms/MainIndex/MainIndex.js:18:22)
    at ServerSearchResults (webpack-internal:///(api)/./src/components/molecules/ServerSearchResults/ServerSearchResults.js:21:32)
Warning: Detected multiple renderers concurrently rendering the same context provider. This is currently unsupported.
    at Index (/node_modules/react-instantsearch-core/dist/cjs/widgets/Index.js:86:34)
    at IndexWrapper (/node_modules/react-instantsearch-core/dist/cjs/widgets/Index.js:157:31)
    at Index (webpack-internal:///(api)/./src/components/organisms/Index/index.js:21:18)
    at InstantSearch (/node_modules/react-instantsearch-core/dist/cjs/widgets/InstantSearch.js:101:34)
    at MainIndex (webpack-internal:///(api)/./src/components/organisms/MainIndex/MainIndex.js:18:22)
    at ServerSearchResults (webpack-internal:///(api)/./src/components/molecules/ServerSearchResults/ServerSearchResults.js:21:32)

@francoischalifour
Copy link
Member

We can't help you further without any snippets or reproduction. The sandbox I sent you uses React 18 and doesn't have this problem, so this likely comes from your application code.

@Haroenv
Copy link
Contributor

Haroenv commented Apr 21, 2022

Do you have the structure of your InstantSearch application and the part which calls findResultsState at least? I'm wondering if this is because of a reused context provider that would not happen if only the InstantSearch app is passed to findResultsState

@DB-Alex
Copy link
Author

DB-Alex commented Apr 21, 2022

Sure, here is the algolia utility:

import algoliasearch from 'algoliasearch/lite';
import { asyncForEach } from 'helpers/core';
import { getIndexName } from 'helpers/search';
import { findResultsState as instantSearchFindResultsState } from 'react-instantsearch-dom/server';
import { logger } from 'utils/logging';

export const searchClient = algoliasearch(
	process.env.NEXT_PUBLIC_ALGOLIA_APP_ID,
	process.env.NEXT_PUBLIC_ALGOLIA_API_KEY,
);

export const findResultsState = async(Component, {
	indexName,
	indexes,
	...props
}) => {
	let resultsState = {};

	try {
		let indexesExist = true;

		await asyncForEach([
			indexName,
			...new Set(indexes),
		], async(searchIndex) => {
			searchIndex = getIndexName({
				indexName: searchIndex,
			});

			if (
				!await searchClient.initIndex(searchIndex).exists()
			) {
				indexesExist = searchIndex;
			}
		});

		if (indexesExist === true) {
			indexName = getIndexName({
				indexName,
			});

			resultsState = await instantSearchFindResultsState(Component, {
				searchClient,
				indexName,
				indexes,
				...props,
			});
		} else {
			logger.warning(`utils/algolia - findResultsState() - Index: ${indexesExist} does not exist`);
		}
	} catch (error) {
		logger.error('utils/algolia - findResultsState() - Error', {
			error,
			indexName,
			props,
		});
	}

	return JSON.parse(JSON.stringify(resultsState));
};

The "Component" getting passed is ServerSearchResults.js

import Index from 'components/organisms/Index';
import MainIndex from 'components/organisms/MainIndex';
import React from 'react';
import { Hits } from 'react-instantsearch-dom';

const ServerSearchResults = ({
	mainIndex,
	indexName,
	indexes,
	preset,
	hitsPerPage = 24,
	...props
}) => {
	if (indexName) {
		if (!mainIndex) {
			mainIndex = indexName;
		}

		if (!indexes) {
			indexes = [indexName];
		}
	}

	if (!indexes || indexes.length === 0) {
		return null;
	}

	return (
		<MainIndex mainIndex={mainIndex} {...props}>
			{indexes.map((indexName, index) => (
				<Index
					key={`${indexName}-${index}`}
					indexName={indexName}
					preset={preset}
					hitsPerPage={hitsPerPage}
				>
					<Hits
						hitComponent={({ hit }) => (
							<React.Fragment>
								{hit.brand} - {hit.name}
							</React.Fragment>
						)}
					/>
				</Index>
			))}
		</MainIndex>
	);
};

export default ServerSearchResults;

@Haroenv
Copy link
Contributor

Haroenv commented Apr 21, 2022

what is in the MainIndex component @DB-Alex ?

@DB-Alex
Copy link
Author

DB-Alex commented Apr 21, 2022

MainIndex component:

import { getIndexName } from 'helpers/search';
import { useInstantSearch } from 'providers/InstantSearchProvider';
import React from 'react';
import { InstantSearch } from 'react-instantsearch-dom';

const MainIndex = ({
	mainIndex,
	children,
	...props
}) => {
	let {
		searchClient,
		resultsState,
		handleSearchStateChange,
		searchState,
	} = useInstantSearch();

	return (
		<InstantSearch
			indexName={getIndexName({
				indexName: mainIndex,
			})}
			searchClient={searchClient}
			resultsState={resultsState}
			onSearchStateChange={handleSearchStateChange}
			searchState={searchState}
			{...props}
		>
			{children}
		</InstantSearch>
	);
};

export default MainIndex;

@Haroenv
Copy link
Contributor

Haroenv commented May 2, 2022

I've managed to reproduce this now with just InstantSearch, but as far as I can tell it has no adverse effects. I wonder how eg. Apollo with a very similar design avoids this warning

@MrSnufalafogus
Copy link

MrSnufalafogus commented May 6, 2022

Any update on this? We are seeing the same issue in our React/Next app after upgrading to React 18.0.0

Some additional info that we found while researching this error:
reactwg/react-18#19
reactwg/react-18#17
reactwg/react-18#18

It may not be causing issues now but from the React blog: https://reactjs.org/blog/2022/03/29/react-v18.html#new-strict-mode-behaviors it looks like it may cause breaking changes in the future.

@Haroenv
Copy link
Contributor

Haroenv commented May 9, 2022

Not yet, sorry! I'm not fully sure whet the underlying cause is, which components are shared since as far as I can tell it's a completely separate "app" tree being created, so I'm not sure which part is the same provider (InstantSearch itself?).

I did find since that Apollo for example avoids this by returning the result of renderToString and asking the user to render that in a simple html wrapper after.

If you have any ideas on what could be the underlying reasons or solution, I'm all ears!

Relevant issues:

@Haroenv Haroenv changed the title BUG - Detected multiple renderers concurrently rendering the same context provider (React 18.0.0?) WARNING - Detected multiple renderers concurrently rendering the same context provider (React 18.0.0?) May 11, 2022
@wenche
Copy link

wenche commented May 25, 2022

We also have the same issue after the upgrade. The culprit for us seems to be the getServerState from react-instantsearch-hooks-server

@Haroenv
Copy link
Contributor

Haroenv commented May 30, 2022

As far as I can tell, this is an incorrect warning from React (facebook/react#22796) and it has no effect apart from giving that warning. Conceptually I haven't found a way to avoid the error except by manually ignoring it

@francoischalifour francoischalifour added the Library: React InstantSearch ≥ 7 Issues in any of the react-instantsearch@7 packages (formerly named react-instantsearch-hooks) label Jun 2, 2022
@Qwal
Copy link

Qwal commented Jun 20, 2022

This issue is reproducible on https://github.com/algolia/pwa-ecom-ui-template after you upgrade React to v18. Could you please check?

@Haroenv
Copy link
Contributor

Haroenv commented Jun 21, 2022

Hey @Qwal, we are aware of this warning, but it doesn't have an impact on the application, but is a result of React counting two distinct renders that happen subsequently as if they happen concurrently (not the case). You can follow in the react issue linked earlier: facebook/react#22796

@Qwal
Copy link

Qwal commented Jun 21, 2022

Hi @Haroenv this is what I see after running the app:
image

It has impact on application ex. SEO & Performance will be downgraded if we do not match the SSR state with CSR state.

We are building POC around Algolia to validate if we can use it for new shop we are building and this is a first obstacle.

If I understand correctly the issue you linked is related to unit testing.

@Haroenv
Copy link
Contributor

Haroenv commented Jun 21, 2022

Ah, what you're showing isn't the same issue as this one originally was about. The state not matching between client and server would indeed be an issue.

When I update the default next example to react 18 it works as expected (https://codesandbox.io/s/admiring-benji-ovjzlk?file=/pages/index.js) so I'm guessing the client mismatch is something due to a specific implementation in the pwa ecom ui template, and thus an issue should be opened there (cc @FabienMotte). I'm not sure yet what the specific issue could be though

The react issue shows up in unit testing, but also in our case of server side rendering with an unneeded warning.

@hutber
Copy link

hutber commented Sep 25, 2022

@Haroenv for me, the only issue with this is, it gets stuck in a repeating loop. I have tried to work out how to break out of it but I can't. Which then leads to this error: https://stackoverflow.com/questions/55763428/react-native-error-enospc-system-limit-for-number-of-file-watchers-reached so I'll need to reset my machine after a little while.

176 after a few seconds :O
image

@Haroenv
Copy link
Contributor

Haroenv commented Sep 26, 2022

@hutber could you open a new issue with reproduction, it seems unrelated

@sarahdayan sarahdayan transferred this issue from algolia/react-instantsearch Dec 22, 2022
@Haroenv Haroenv added Library: React InstantSearch < 7 Issues in any of the react-instantsearch@6 packages Resolution: Wontfix labels Jan 12, 2023
@Haroenv
Copy link
Contributor

Haroenv commented Jan 12, 2023

This issue has been closed in React, as it was unintentional. In the next release of react this warning will no longer show.

see: facebook/react#22797 (comment)

@Haroenv Haroenv closed this as not planned Won't fix, can't repro, duplicate, stale Jan 12, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Library: React InstantSearch < 7 Issues in any of the react-instantsearch@6 packages Library: React InstantSearch ≥ 7 Issues in any of the react-instantsearch@7 packages (formerly named react-instantsearch-hooks) Resolution: Wontfix
Projects
None yet
Development

No branches or pull requests

7 participants