路由加状态管理的登录拦截综合案例

90 阅读1分钟

src/index

image.png

App.jsx

image.png

APP.css

image.png


.App .navbar{
  position: absolute;
  bottom: 0;
  width: 100%;
  height: 30px;
  display: flex;
  align-items: center;
}
.App .navbar a{
  flex: 1;
  text-align: center;
}
.App .navbar .active{
  background: red;
  color: white;
}

三个views文件、

image.png

Login

import React from 'react'
import { useRef } from 'react'
import { useDispatch } from 'react-redux'
import { useNavigate } from 'react-router-dom'

export default function Login() {
  const dispatch = useDispatch()
  const elemInput = useRef()
  const navigate = useNavigate()
  const handleClick = () => {
    dispatch({
      type: 'user/change',
      payload: elemInput.current.value
    })
    navigate('/user')
  }
  return (
    <div>
      <h2>Login</h2>
      <input type="text" ref={elemInput} />
      <button onClick={handleClick}>登录</button>
    </div>
  )
}

User

import React from 'react'
import { useSelector } from 'react-redux'

export default function User() {
  const name = useSelector((state)=> state.user.name)
  return (
    <div>
      <h2>User:{name}</h2>
    </div>
  )
}

Index

import React from 'react'

export default function Index() {
  return (
    <div>
      <h2>Index</h2>
    </div>
  )
}

store/index

image.png

import { configureStore } from '@reduxjs/toolkit'
import userReducer from './modules/user';

const store = configureStore({
  reducer: {
    user: userReducer
  }
})
export default store;

user

import { createSlice } from '@reduxjs/toolkit'

const userSlice = createSlice({
  name: 'user',
  initialState: {
    name: ''
  },
  reducers: {
    change(state, action){
      state.name = action.payload
    }
  }
})

export default userSlice.reducer

router

import { createBrowserRouter, Navigate, redirect } from 'react-router-dom'

import App from '../App';
import Index from '../views/Index/Index';
import User from '../views/User/User';
import Login from '../views/Login/Login';
import store from '../store';

export const routes = [
  {
    path: '/',
    element: <App />,
    children: [
      {
        index: true,
        element: <Navigate to="/index" />
      },
      {
        path: 'index',
        element: <Index />
      },
      {
        path: 'user',
        element: <User />,
        loader(){
          if(!store.getState().user.name){
            return redirect('/login')
          }
        }
      },
      {
        path: 'login',
        element: <Login />
      }
    ]
  }
];

const router = createBrowserRouter(routes);

export default router;

image.png