'React Router v2.7 to v6 onEnter Migration

I am trying to migrate an application running on router v3, using the onEnter attribute for route after auth.

onEnter function in YAMain.jsx

    static onEnter(store) {
        return (nextState, replaceState, callback) => {

            // Check if the user is logged in and allowed to make requests before letting them proceed
            store.dispatch({
                type: IS_LOGGED_IN,
                onLoggedIn: () => {
                    store.dispatch({
                        type: GET_SELECTED_LOCATION_AND_CLASSROOM,
                        onSuccess: callback,
                        onFailure: () => {

                            // Get all of the required information from the store
                            const profile = getProfile(store.getState());
                            const selectedClassroom = getSelectedClassroom(store.getState());
                            const selectedLocation = getSelectedLocation(store.getState());

                            // No location has been selected by an admin, go to the locations page
                            if (profile.get('accessLevel') !== 'E' && !selectedLocation.get('id')) {

                                // Return early if this is the page we are going to
                                if (nextState.location.pathname.startsWith('/location')) {
                                    return callback();
                                }

                                replaceState('/location');
                                return callback();
                            }

                            // No classroom has been selected by a user, go to the classrooms page
                            if (!selectedClassroom.get('id')) {

                                // Return early if this is the page we are going to
                                if (nextState.location.pathname.startsWith('/classroom')) {
                                    return callback();
                                }

                                replaceState('/classroom');
                                return callback();
                            }

                            return callback();
                        }
                    });
                },
                onNotLoggedIn: () => {
                    replaceState('/login');
                    callback();
                },
                onFailure: (error) => {
                    if (isTimeGateError(error)) {
                        replaceState('/locked');
                        callback();
                    }
                }
            });
        };

render function in YARouter.jsx, both classes extend component.

    render() {
        return (
            <BrowserRouter>
                <Routes>
                    {/* Handles the main logic and renders all but one of the pages */}
                    <Route
                        exact path="/"
                        element={<YAMain/>
                        }
                        onEnter={YAMain.onEnter(this.props.store)}
                    >
                        <Route path="/" element={YADashboard}/>

                        {/* Locations page displays the available list of locations */}
                        <Route
                            path="location"
                            element={YALocations}
                        />

                        {/* Classrooms page displays the available list of classrooms */}
                        <Route
                            path="classroom"
                            element={YAClassrooms}
                        />

this is not the entirety of the routing but should be enough to give you an idea of what's going on.

This is what I have now, I have tried a number of things suggested on various places. I'm trying to understand how I can either make this work so I can move on and work on this and make it proper later, OR make it proper now and fix this issue.

How can I go about ensuring proper redirection for user authentication, I've spent 2 days at work trying to figure anything out and am completely stuck.

Thanks.



Solution 1:[1]

If you are just looking for a way to call onEnter when the route is matched and rendered then I think calling it in a mounting useEffect hook in a wrapper component is probably what you are after.

Example:

const YAMainWrapper = ({ children, onEnter }) => {
  useEffect(() => {
    onEnter();
  }, []);

  return children;
};

...

render() {
  return (
    <BrowserRouter>
      <Routes>
        {/* Handles the main logic and renders all but one of the pages */}
        <Route
          path="/"
          element={(
            <YAMainWrapper onEnter={YAMain.onEnter(this.props.store)}>
              <YAMain />
            </YAMainWrapper>
          )}
        >
          <Route path="/" element={<YADashboard />} />

          {/* Locations page displays the available list of locations */}
          <Route path="location" element={<YALocations />} />

          {/* Classrooms page displays the available list of classrooms */}
          <Route path="classroom" element={<YAClassrooms />} />

          ...

        </Route>

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 Drew Reese