'Routes not working in react even when trying to use Routes and Router
I'm following this tutorial: https://ibaslogic.com/routing-with-react-router/
When I render the page, I recieve this error
Uncaught Error: A <Route> is only ever to be used as the child of <Routes> element, never rendered directly. Please wrap your <Route> in a <Routes>.
at invariant (bundle.js:61876)
at Route (bundle.js:62025)
at renderWithHooks (bundle.js:23504)
at mountIndeterminateComponent (bundle.js:26266)
at beginWork (bundle.js:27465)
at HTMLUnknownElement.callCallback (bundle.js:12454)
at Object.invokeGuardedCallbackDev (bundle.js:12503)
at invokeGuardedCallback (bundle.js:12563)
at beginWork$1 (bundle.js:32305)
at performUnitOfWork (bundle.js:31141)
I've tried to wrap the Route in Routes as the warning suggests. I still get an error that I need Router which I already have. I've also tried the suggestions here react-router, routes not working without success
Here is my js component file where the error is taking place:
import React, { useState, useEffect } from "react"
import TodosList from "./TodosList";
import Header from "./Header";
import InputTodo from "./InputTodo";
import { v4 as uuidv4 } from "uuid";
import "./App.css"
import { Route, Switch } from "react-router-dom"
const TodoContainer = () => {
const [todos, setTodos] = useState(getInitialTodos())
const handleChange = id => {
setTodos(prevState =>
prevState.map(todo => {
if (todo.id === id) {
return {
...todo,
completed: !todo.completed,
}
}
return todo
})
)
}
const delTodo = id => {
setTodos([
...todos.filter(todo => {
return todo.id !== id
}),
])
}
const addTodoItem = title => {
const newTodo = {
id: uuidv4(),
title: title,
completed: false,
}
setTodos([...todos, newTodo])
}
const setUpdate = (updatedTitle, id) => {
setTodos(
todos.map(todo => {
if (todo.id === id) {
todo.title = updatedTitle
}
return todo
})
)
}
// useEffect(() => {
// console.log("test run")
// // getting stored items
// const temp = localStorage.getItem("todos")
// const loadedTodos = JSON.parse(temp)
// if (loadedTodos) {
// setTodos(loadedTodos)
// }
// }, [])
function getInitialTodos() {
// getting stored items
const temp = localStorage.getItem("todos")
const savedTodos = JSON.parse(temp)
return savedTodos || []
}
useEffect(() => {
// storing todos items
const temp = JSON.stringify(todos)
localStorage.setItem("todos", temp)
}, [todos])
return (
<Route path="/">
<div className="container">
<div className="inner">
<Header />
<InputTodo addTodoProps={addTodoItem} />
<TodosList
todos={todos}
handleChangeProps={handleChange}
deleteTodoProps={delTodo}
setUpdate={setUpdate}
/>
</div>
</div>
</Route>
)
}
export default TodoContainer
Here is my index.js:
import React from "react"
import ReactDOM from "react-dom"
//component file
import TodoContainer from "./functionBased/components/TodoContainer"
import { BrowserRouter as Router } from "react-router-dom"
//stylesheet
import "./functionBased/App.css"
ReactDOM.render(
<React.StrictMode>
<Router>
<TodoContainer />
</Router>
</React.StrictMode>,
document.getElementById("root")
)
I'm unsure how to make Route work.
Solution 1:[1]
You are supposed to declare your Route in the Routes component. So you should first wrap the TodoContainer in the Routes component and then put the element you want to render in the element property of the Route component
ReactDOM.render(
<React.StrictMode>
<Router>
<Routes>
<Route path="/" element={<TodoContainer />}/>
</Routes>
</Router>
</React.StrictMode>,
document.getElementById("root")
)
Then, you don't need to handle the routing anymore in the TodoContainer
Take a look at the documentation to learn more about routing (this is the react router v6 here)
Solution 2:[2]
Not sure I understand the problem correctly but maybe try in the index.js to change
<TodoContainer />
with:
<Route exact path="/" element={<TodoContainer />}/>
also remember to import Route from react-router-dom
import {BrowserRouter as Router, Route} from 'react-router-dom';
This blogpost by Esteban Herrera gives a good example on how to use react router. https://blog.logrocket.com/react-router-dom-tutorial-examples/
Solution 3:[3]
I think you need to do something like that:
- remove Route tag from your component folder
- add Route tag to your index.js file like that
import {BrowserRouter as Router, Route} from 'react-router-dom';
...
<Router>
<Route exact path="/" element={<TodoContainer />}/>
</Router>
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | TheTisiboth |
| Solution 2 | jamie.russell450 |
| Solution 3 | Ahmed Khaled |
