React not redirecting as intended when A function is called in the Routes route
I am building a login and logout system for a react project of mine. I have a navbar setup and I am using react-redirect-dom
to create links and redirect links to different pages in order to manage the login system.
In the current project, I have a route that does the processing for the login in the login component. I have another link that processes the signup within the signup component.
For the logout, If a user is logged in and they use the /logout
endpoint, I want it to immediately call the handleLogout
function and log the user out and reroute to the /
endpoint
Here is the code I have and the error:
function App() {
const [loggedIn, setLoggedIn] = useState(false)
const [currentUser, setCurrentUser] = useState('')
function handleLogout() {
console.log('handle logout')
axios.post('/api/auth/logout', {
"username":currentUser.username,
"password":currentUser.password,
})
.then((data) => {
console.log(data.data)
setCurrentUser(data.data)
setLoggedIn(false)
return(<Navigate to='/' />)
})
.catch((err) => {
console.log(err)
})
}
return (
<div className="App">
{/* <ContentContext value={contentContextValue}> */}
<BrowserRouter>
<Routes>
<Route exact path="/" element={loggedIn ? <Feed/> : <Login setLoggedIn={setLoggedIn} setCurrentUser={setCurrentUser}/>} />
<Route exact path="/login" element={<Login setLoggedIn={setLoggedIn} setCurrentUser={setCurrentUser}/>}/>
<Route exact path="/signup" element={<Login setLoggedIn={setLoggedIn} setCurrentUser={setCurrentUser}/>}/>
<Route exact path="/logout" element={loggedIn ? () => {handleLogout()} : <Login/>}/>
</Routes>
</BrowserRouter>
{/* </ContentContext> */}
</div>
);
}
Here is the error:
Warning: Functions are not valid as a React child. This may happen if you return a Component instead of <Component /> from render. Or maybe you meant to call this function rather than return it.
**************** UPDATE ***********************
import React from 'react'
export default function Logout(props) {
const {
handleLogout
} = props
const Logout = ({ handleLogout }) => {
const navigate = useNavigate();
React.useEffect(() => {
handleLogout();
navigate("/", { replace: true });
}, []);
return null;
};
return (
<div>
</div>
)
}
Solution 1:
In react-router-dom
version 6 the Route
components take an element
prop that takes only a ReactElement
, a.k.a. JSX. Passing a function here is invalid, as the warning points out.
Refactor your logout logic into a component in a mounting useEffect
hook. Invoke the passed handleLogout
function and then imperatively redirect to the home "/"
path.
const Logout = ({ handleLogout }) => {
const navigate = useNavigate();
React.useEffect(() => {
handleLogout();
navigate("/", { replace: true });
}, []);
return null;
};
...
<Routes>
<Route
path="/"
element={loggedIn
? <Feed />
: <Login setLoggedIn={setLoggedIn} setCurrentUser={setCurrentUser} />
}
/>
<Route
path="/login"
element={<Login setLoggedIn={setLoggedIn} setCurrentUser={setCurrentUser} />}
/>
<Route
path="/signup"
element={<Login setLoggedIn={setLoggedIn} setCurrentUser={setCurrentUser} />}
/>
<Route
path="/logout"
element={loggedIn
? <Logout handleLogout={handleLogout} />
: <Login />
}
/>
</Routes>