私有路由的最佳实践是什么?也许我做错了什么,但当用户登录时,我已经被重定向到/login页面
我的第二个问题是:这些版本中哪一个更好,或者你有更好的 idea ?
代码:
认证
const authSlice = createSlice({
name: 'auth',
initialState: {
user: {},
isUserLoggedIn: null,
isLoading: false,
},
reducers: {},
extraReducers: (builder) => {
builder
.addCase(me.pending, (state) => {
state.isLoading = true
})
.addCase(me.fulfilled, (state, action) => {
state.user = action.payload.userData
state.isUserLoggedIn = true
state.isLoading = false
})
.addCase(me.rejected, (state) => {
state.isUserLoggedIn = false
})
},
})
export const me = createAsyncThunk('auth/me', async () => {
try {
const user = await userService.getUserData()
return { userData: user.data.data }
} catch (error) {
const message =
(error.response && error.response.data && error.response.data.message) ||
error.message ||
error.toString()
return message
}
})
CASE 1:
应用程序
function 应用程序() {
const dispatch = useDispatch()
useEffect(() => {
dispatch(me())
}, [])
const auth = useSelector((state) => state.auth)
return (
<div data-theme={theme}>
<BrowserRouter>
<应用程序路由 is认证enticated={auth.isUserLoggedIn} />
</BrowserRouter>
</div>
)
}
export default 应用程序
路由
export const 应用程序路由 = ({ is认证enticated }) => (
<路由>
<Route
path='/login'
element={<Login />}
/>
<Route
path='/dashboard'
element={
<私密路由 is认证enticated={is认证enticated}>
<Stats />
</私密路由>
}
/>
...
私密路由
export const 私密路由 = ({ children, is认证enticated }) => {
return is认证enticated ? children : <Navigate to='/login' />
}
CASE 2:
应用程序
function 应用程序() {
return (
<div data-theme={theme}>
<BrowserRouter>
<应用程序路由 />
</BrowserRouter>
</div>
)
}
export default 应用程序
路由
export const 应用程序路由 = () => (
<路由>
<Route
path='/login'
element={<Login />}
/>
<Route
path='/dashboard'
element={
<私密路由>
<Stats />
</私密路由>
}
/>
...
私密路由
export const 私密路由 = ({ children }) => {
const dispatch = useDispatch()
const { isUserLoggedIn } = useSelector((state) => state.auth)
useEffect(() => {
if (isUserLoggedIn === null) {
dispatch(me())
}
}, [])
return isUserLoggedIn ? children : <Navigate to='/login' />
}
case 1或 case 2更适合处理,或者你有更好的 idea ?
对于这两个 idea ,当我转到/dashboard时,它会很快重定向到/login
我想要实现的是良好的实践、快速的验证,并等待我们从后端收到用户经过身份验证的肯定响应
团队,你有什么建议?
EDIT
新版本:
Redux
const authSlice = createSlice({
name: 'auth',
initialState: {
user: {},
isUserLoggedIn: null,
isLoading: true,
},
reducers: {},
extraReducers: (builder) => {
builder
.addCase(me.pending, (state) => {
state.isLoading = true
})
.addCase(me.fulfilled, (state, action) => {
state.user = action.payload.userData
state.isUserLoggedIn = true
state.isLoading = false
})
.addCase(me.rejected, (state) => {
state.isLoading = false
state.isUserLoggedIn = false
})
},
})
export const me = createAsyncThunk('auth/me', async ({}, thunkAPI) => {
try {
const user = await userService.getUserData()
return { userData: user.data.data }
} catch (error) {
const message =
(error.response && error.response.data && error.response.data.message) ||
error.message ||
error.toString()
thunkAPI.rejectWithValue(message)
return message
}
})
私密路由
export const 私密路由 = ({ children }) => {
const dispatch = useDispatch()
const { isLoading, isUserLoggedIn } = useSelector((state) => state.auth)
if (isLoading) return null
return isUserLoggedIn ? (
children
) : (
<Navigate
to='/login'
replace
/>
)
}
应用程序
function 应用程序() {
const dispatch = useDispatch()
const { isUserLoggedIn } = useSelector((state) => state.auth)
useEffect(() => {
if (isUserLoggedIn === null) {
dispatch(me())
}
}, [])
return (
<div data-theme={theme}>
<BrowserRouter>
<应用程序路由 />
</BrowserRouter>
</div>
)
}
export default 应用程序
Store
import { configureStore, getDefaultMiddleware } from '@reduxjs/toolkit'
import authReducer from '../features/auth/authSlice'
export const store = configureStore({
reducer: {
auth: authReducer,
},
middleware: (getDefaultMiddleware) =>
getDefaultMiddleware({ serializableCheck: false }),
})
Index.js
ReactDOM.render(
<React.StrictMode>
<Provider store={store}>
<应用程序 />
</Provider>
</React.StrictMode>,
document.getElementById('root')
但是当我重新加载页面时,我会转到/login
,不要停留在同一页面上,比如/dashboard
,我该怎么处理呢?