I have a parent React component, CreateTopMenuResultPage
which was called when a search button was clicked. Search button opened a new result page and CreateTopMenuResultPage
was rendered in div id result-page-sort-menu
in that result page. All components rendered fine
I started getting these errors when I changed my whole solution to use react-router-dom and introduced routing.
Currently , on server, my app, which does not have react-router-dom yet and has the same hooks logic as my local is working fine.
Errors encountering:
Rendered more hooks than during the previous render.
and
Invalid hook call. Hooks can only be called inside of the body of a function..
Errors point to whereever I am using useState
So I am guessing , it might have to do something with 1. mismatching versions of React and React DOM. or 2.more than one copy of React
I get true for this check - window.React1 === window.React2
as is mentioned in react debug docs here
As mentioned in above react doc link , when I run npm ls react-dom
, I get this tree
├─┬ @wordpress/[email protected]
│ ├─┬ @wordpress/[email protected]
│ │ └─┬ @wordpress/[email protected]
│ │ └── [email protected] deduped
│ └── [email protected]
├─┬ [email protected]
│ ├─┬ [email protected]
│ │ └── [email protected] deduped
│ └── [email protected] deduped
└─┬ [email protected]
└── [email protected] deduped
Any help is appreciated
EDIT
This is the tree from my server where the same hooks logic is working fine
├─┬ @wordpress/[email protected]
│ ├─┬ @wordpress/[email protected]
│ │ └─┬ @wordpress/[email protected]
│ │ └── [email protected] deduped
│ ├─┬ [email protected]
│ │ └── [email protected] deduped
│ └── [email protected]
└─┬ [email protected]
├─┬ [email protected]
│ └── [email protected] deduped
└── [email protected] deduped
Based on that , I guess, it is not react mismatching or more copies of react that is causing these error . But I may be incorrect
It may have to do something with using react-router-dom
I am using routing like this
let navigate = useNavigate();
function handleSearch() {
navigate('/search');
}
return(
...
<a href="#" className="theme-btn w-100 text-center margin-top-20px"
onClick={handleSearch }
>
Search Now
</a>
...
);
Is there an issue to use useNavigate()
like that
Although I had a vague feeling that I am doing something wrong when I am using two ReactDOM.render
in my solution one in index.js
and other one in RenderTopMenuResultPage
, the comment made by @Drew Reese ( many thanks!) in above comments made me to think again and consider an approach where only one react tree should generate as it sounded right in terms of doing things in react.
So now , I changed this
export const RenderTopMenuResultPage = (props) => {
ReactDOM.render(
<CreateTopMenuResultPage />,
document.getElementById('result-page-sort-menu')
)
}
to
export const RenderTopMenuResultPage = (props) => {
return <CreateTopMenuResultPage />;
};
and my index.js is
ReactDOM.render(
<BrowserRouter>
<AppRouter /> , <HomePageFlightContainer />
</BrowserRouter>,
document.getElementById('search-flights-container')
)
Approuter.js is
export const AppRouter = () => {
return (
<div >
<Routes>
<Route path="/" element={<HomePageFlightContainer/>} />
<Route path="/search" element={<RenderTopMenuResultPage />} />
{/* <Route path="/" component={<HomePageFlightContainer/> } />*/}
{/* <Route path="/wordpress/search" component={<PageFetch />} />*/}
</Routes>
</div>
);
};
and also included conditional element where search button is located. This element will render RenderTopMenuResultPage
, which in turn will render CreateTopMenuResultPage
<a href="#" className="theme-btn w-100 text-center margin-top-20px"
onClick={handleSearch }
>
Search Now
</a>
{showResults && (
<div id="result-page-sort-menu">
<p>This is where search results will be displayed.</p>
</div>
)}
and all errors disappeared
Summary : There was no issue with hooks logic , mismatching versions of React and React DOM , more than one copy of React Or using useNavigate() , the way I am using
Although they may be an issue in some scenarios, in this particular scenario the issue was using two ReactDOM.render