2

Recently, I am facing issue with Custom Route with latest react-router-dom version 6 in my code. I have created custom route for authorized if user is not login then it will redirect to sign in page. It was working with previous react router version but now it's got broke with latest one. I am posting the code below.

Getting below error message as well. [UserRoute] is not a component. All component children of must be a Route or <React.Fragment>

LoadingToRedirect.js

import React, { useState, useEffect } from "react";
import { useNavigate } from "react-router-dom";

const LoadingToRedirect = () => {
  const [count, setCount] = useState(5);
  const navigate = useNavigate();

  useEffect(() => {
    const interval = setInterval(() => {
      setCount((currentCount) => --currentCount);
    }, 1000);

    count === 0 && navigate("/login");
    return () => clearInterval(interval);
  }, [count, navigate]);
  return (
    <div>
      <p>Redirecting you in {count} seconds</p>
    </div>
  );
};

export default LoadingToRedirect;

UserRoute.js

import React from "react";
import { Route, Routes } from "react-router-dom";
import { useSelector } from "react-redux";
import LoadingToRedirect from "./LoadingToRedirect";

const UserRoute = ({ children, ...rest }) => {
  const { currentUser } = useSelector((state) => state.user);
  return currentUser ? <Route {...rest} /> : <LoadingToRedirect />;
};

export default UserRoute;

App.js

import React, { useEffect, Fragment } from "react";
import "./App.css";
import { BrowserRouter, Routes, Route } from "react-router-dom";
import Home from "./pages/Home";
import Login from "./pages/Login";
import Register from "./pages/Register";
import UserRoute from "./components/UserRoute";
import { useDispatch } from "react-redux";
import { auth } from "./firebase";
import { setUser } from "./redux/actions";
import Header from "./components/Header";
import AddEdit from "./pages/AddEdit";
function App() {
  const dispatch = useDispatch();

  useEffect(() => {
    auth.onAuthStateChanged((authUser) => {
      if (authUser) {
        dispatch(setUser(authUser));
      } else {
        dispatch(setUser(null));
      }
    });
  }, [dispatch]);
  return (
    <BrowserRouter>
      <div className="App">
        <Header />
        <ToastContainer position="top-center" />
        <Fragment>
          <Routes>
            <UserRoute path="/" element={<Home />} />
            <Route path="/login" element={<Login />} />
            <Route path="/register" element={<Register />} />
            <UserRoute path="/addContact" element={<AddEdit />} />
          </Routes>
        </Fragment>
      </div>
    </BrowserRouter>
  );
}

export default App;
James
  • 371
  • 3
  • 12

1 Answers1

1

In react-router v6, the Routes component allows only Route children.

In UserRoute.js if there's no user you are returning LoadingToRedirect:

 return currentUser ? <Route {...rest} /> : <LoadingToRedirect />;

You can try changing this to:

const UserRoute = ({ children, path, element }) => {
  const { currentUser } = useSelector((state) => state.user);
  return  <Route path={path} element={ currentUser ? element : <LoadingToRedirect />} />;
};
adrianmanduc
  • 846
  • 6
  • 10