The react-router-dom
warning “Warning: Functions are not valid as a React child. This may happen if you return a Component instead of from render. Or maybe you meant to call this function rather than return it.” is caused by setting the element
property of a <Route>
component to the name of the component rather than the tag version of that component. To fix this, ensure you set element
to <Component />
instead of Component
.
In react-router-dom
, you set the component that will render for a particular route by setting the <Route>
component’s element
property. Unlike some other libraries, however, you do not set that property to the name of the component you want rendered. Rather, you have to set it to the tag version of that component.
Let’s look at an example.
Problem: you set the element property in a Route component to the name of a component rather than an instance of it
Below is an example of some routes that were set up for our react-router-dom
tutorial. If you want a more in-depth look at how to use react-router-dom
, check out that article.
import { Provider } from "urql";
import { urqlClient } from "./utils";
import { HashRouter, Route, Routes, Link } from "react-router-dom";
import MessagesPage from "./MessagesPage";
import UsersPage from "./UsersPage";
function App() {
return (
<Provider value={urqlClient}>
<HashRouter>
<div id="menu">
Menu:
<Link to="/">Home</Link>
<Link to="/users">Users</Link>
</div>
<Routes>
<Route path="/" element={MessagesPage} />
<Route path="/users" element={UsersPage} />
</Routes>
</HashRouter>
</Provider>
);
}
export default App;
JavaScriptYou’ll notice that we’ve set up two routes, /
and /users
. However, we’ve made a mistake while doing so:
<Routes>
<Route path="/" element={MessagesPage} />
<Route path="/users" element={UsersPage} />
</Routes>
</HashRouter>
JavaScriptAs you can see above, we accidentally set the element
property to the name of the component we want rendered rather than an instance of the component. When we try to run this in our browser, we’ll get a blank space where the component for our route should be, and the following warning in our dev console:
As the error above implies, React components can’t return functions, they have to return other components. This might sound a little confusing at first, and this error doesn’t come right out and say that it has anything to do with react-router-dom
. But it can help to think of it this way: when you refer to a component as Component
, you’re actually referring to the function that generates that component. When you refer to it as <Component />
, though, you’re referring to the result of calling that function, which is an actual instance of that component.
Hopefully that all made sense. Fixing this is pretty simple, so let’s look at the solution next.
Solution: set the element property to an instance of a component
Highlighted below is how we fixed this:
import { Provider } from "urql";
import { urqlClient } from "./utils";
import { HashRouter, Route, Routes, Link } from "react-router-dom";
import MessagesPage from "./MessagesPage";
import UsersPage from "./UsersPage";
function App() {
return (
<Provider value={urqlClient}>
<HashRouter>
<div id="menu">
Menu:
<Link to="/">Home</Link>
<Link to="/users">Users</Link>
</div>
<Routes>
<Route path="/" element={<MessagesPage />} />
<Route path="/users" element={<UsersPage />} />
</Routes>
</HashRouter>
</Provider>
);
}
export default App;
JavaScriptAll you have to do is put your component you want rendered as a tag instead of putting the name of the component as the value of element
. Now it should render properly.
Conclusion
In react-router-dom
, you have to put an instance of a component as the value of the element
property in a <Route>
component, otherwise you’ll get the warning “Warning: Functions are not valid as a React child. This may happen if you return a Component instead of from render. Or maybe you meant to call this function rather than return it”. It’s an easy mistake to make, since lots of React libraries do want you to pass the name rather than an instance of a component as a property.
John is a professional software engineer who has been solving problems with code for 15+ years. He has experience with full stack web development, container orchestration, mobile development, DevOps, Windows and Linux kernel development, cybersecurity, and reverse engineering. In his spare time, he’s researching the potential business applications of AI.