为什么在使用 React Router V6 保护路由时,我使用 AWS Amplify 的 React Authentication 组件会被无限渲染
Why is my React Authentication component using AWS Amplify being rendered infinitely when using React Router V6 to protect routes
我正在尝试使用 React、AWS Amplify 和 React Router V6 创建我自己的自定义身份验证,我的目标是保护某些路由,以便未登录的用户无法访问它们。
我的代码在这里:
import './App.css';
import { ThemeProvider, createTheme } from '@mui/material/styles';
import Navbar from './components/Navbar/Navbar';
import Dashboard from './components/Dashboard/Dashboard';
import Reports from './components/Reports/Reports';
import Patients from './components/Patients/Patients';
import { BrowserRouter, Navigate, Outlet, Route, Routes, useLocation, } from 'react-router-dom';
import React, { useEffect, useState } from 'react';
import '@aws-amplify/ui-react/styles.css';
import Signup from './components/Signup/Signup';
import Signin from './components/Signin/Signin';
import { Auth } from 'aws-amplify';
const darkTheme = createTheme({
palette: {
mode: 'dark',
}
});
const useAuth = () => {
const [user, setUser] = useState(null);
useEffect(() => {
const fetchUser = async () => {
const response = await Auth.currentAuthenticatedUser();
setUser(response);
}
fetchUser();
})
return { user };
}
function RequireAuth() {
const auth = useAuth();
const location = useLocation();
console.log(auth);
return (
auth
? <Outlet/>
: <Navigate to='/signin' state={{ from: location}} replace/>
);
}
const App = () => {
return (
<ThemeProvider theme={darkTheme}>
<BrowserRouter>
<Routes>
<Route element={<RequireAuth />}>
<Route path="/" element={<Navbar />}>
<Route path="dashboard" element={<Dashboard />} />
<Route path="patients" element={<Patients />} />
<Route path="reports" element={<Reports />} />
</Route>
</Route>
<Route path="/signin" element={<Signin />} />
<Route path="/signup" element={<Signup />} />
</Routes>
</BrowserRouter>
</ThemeProvider>
);
}
export default App;
我花了一整天的时间尝试了无数种方法,但我总是得到相同的结果。我想做的是保护 3 条路线仪表板、患者和报告。每当我点击登录按钮时,我都会得到大约 500 条当前用户的日志,如下所示:
有谁知道是什么触发了这个组件无限地重新渲染(因此执行了我的 console.log(user) 函数),有什么解决方案可以解决这个问题吗?
useEffect
挂钩似乎缺少依赖项数组,因此每个渲染周期都会触发其回调。由于效果会更新状态,因此会触发重新渲染。
添加依赖数组。
useEffect(() => {
const fetchUser = async () => {
const response = await Auth.currentAuthenticatedUser();
setUser(response);
}
fetchUser();
}, []);
如果你需要在路由挂载的时候多次运行这个效果,那么你可能需要添加一个依赖,比如location
if/when 路由路径变化。
示例:
const { pathname } = useLocation();
useEffect(() => {
const fetchUser = async () => {
const response = await Auth.currentAuthenticatedUser();
setUser(response);
}
fetchUser();
}, [pathname]);
由于 useEffect
挂钩 运行 在初始渲染周期结束时,您可能还需要有条件地等待渲染出口或重定向,直到填充 user
状态.
示例:
const useAuth = () => {
const [user, setUser] = useState(); // <-- initially undefined
useEffect(() => {
const fetchUser = async () => {
const response = await Auth.currentAuthenticatedUser();
setUser(response);
}
fetchUser();
}, []);
return { user };
}
...
function RequireAuth() {
const auth = useAuth();
const location = useLocation();
if (auth === undefined) {
return null; // or loading indicator, etc...
}
return (
auth
? <Outlet/>
: <Navigate to='/signin' state={{ from: location }} replace/>
);
}
我正在尝试使用 React、AWS Amplify 和 React Router V6 创建我自己的自定义身份验证,我的目标是保护某些路由,以便未登录的用户无法访问它们。
我的代码在这里:
import './App.css';
import { ThemeProvider, createTheme } from '@mui/material/styles';
import Navbar from './components/Navbar/Navbar';
import Dashboard from './components/Dashboard/Dashboard';
import Reports from './components/Reports/Reports';
import Patients from './components/Patients/Patients';
import { BrowserRouter, Navigate, Outlet, Route, Routes, useLocation, } from 'react-router-dom';
import React, { useEffect, useState } from 'react';
import '@aws-amplify/ui-react/styles.css';
import Signup from './components/Signup/Signup';
import Signin from './components/Signin/Signin';
import { Auth } from 'aws-amplify';
const darkTheme = createTheme({
palette: {
mode: 'dark',
}
});
const useAuth = () => {
const [user, setUser] = useState(null);
useEffect(() => {
const fetchUser = async () => {
const response = await Auth.currentAuthenticatedUser();
setUser(response);
}
fetchUser();
})
return { user };
}
function RequireAuth() {
const auth = useAuth();
const location = useLocation();
console.log(auth);
return (
auth
? <Outlet/>
: <Navigate to='/signin' state={{ from: location}} replace/>
);
}
const App = () => {
return (
<ThemeProvider theme={darkTheme}>
<BrowserRouter>
<Routes>
<Route element={<RequireAuth />}>
<Route path="/" element={<Navbar />}>
<Route path="dashboard" element={<Dashboard />} />
<Route path="patients" element={<Patients />} />
<Route path="reports" element={<Reports />} />
</Route>
</Route>
<Route path="/signin" element={<Signin />} />
<Route path="/signup" element={<Signup />} />
</Routes>
</BrowserRouter>
</ThemeProvider>
);
}
export default App;
我花了一整天的时间尝试了无数种方法,但我总是得到相同的结果。我想做的是保护 3 条路线仪表板、患者和报告。每当我点击登录按钮时,我都会得到大约 500 条当前用户的日志,如下所示:
有谁知道是什么触发了这个组件无限地重新渲染(因此执行了我的 console.log(user) 函数),有什么解决方案可以解决这个问题吗?
useEffect
挂钩似乎缺少依赖项数组,因此每个渲染周期都会触发其回调。由于效果会更新状态,因此会触发重新渲染。
添加依赖数组。
useEffect(() => {
const fetchUser = async () => {
const response = await Auth.currentAuthenticatedUser();
setUser(response);
}
fetchUser();
}, []);
如果你需要在路由挂载的时候多次运行这个效果,那么你可能需要添加一个依赖,比如location
if/when 路由路径变化。
示例:
const { pathname } = useLocation();
useEffect(() => {
const fetchUser = async () => {
const response = await Auth.currentAuthenticatedUser();
setUser(response);
}
fetchUser();
}, [pathname]);
由于 useEffect
挂钩 运行 在初始渲染周期结束时,您可能还需要有条件地等待渲染出口或重定向,直到填充 user
状态.
示例:
const useAuth = () => {
const [user, setUser] = useState(); // <-- initially undefined
useEffect(() => {
const fetchUser = async () => {
const response = await Auth.currentAuthenticatedUser();
setUser(response);
}
fetchUser();
}, []);
return { user };
}
...
function RequireAuth() {
const auth = useAuth();
const location = useLocation();
if (auth === undefined) {
return null; // or loading indicator, etc...
}
return (
auth
? <Outlet/>
: <Navigate to='/signin' state={{ from: location }} replace/>
);
}