React-router-dom 状态改变时不重新渲染 Switch
React-router-dom not re rendering Switch when state is change
我在我的项目中使用 aws-amplify、react-hook。该应用程序有一些私有路由已定义如下:
const ProtectedRoute = ({render: C, props: childProps, ...rest}) => {
return (
<Route
{...rest}
render={rProps =>
(childProps) ? (
<C {...rProps} {...childProps} />
) : (
<Redirect
to={`/login?redirect=${rProps.location.pathname}${
rProps.location.search
}`}
/>
)
}
/>
);
}
在App.js中,我们更改childProps来定义用户是否登录。但是当childProps改变时,Switch不会重新渲染。强制 React 重新渲染其路由的方法是什么,因为 isAuthenticated 已更改但 ProtectedRoute 未重新渲染。
const [isAuthenticated, userHasAuthenticated] = useState(null);
useEffect(() => {
onLoad();
}, []);
async function onLoad() {
try {
let user = await Auth.currentSession();
if (user.accessToken.payload) {
userHasAuthenticated(user.accessToken.payload);
}
} catch (e) {
if (e !== 'No current user') {
alert(e);
}
}
}
.....
const childProps = isAuthenticated;
return (
<ApolloProvider client={client} >
<div className="App">
<BrowserRouter>
<Route path='/'>
<div>
<Switch>
<Route path='/login' render={props => <Login {...props}/>} exact/>
<ProtectedRoute
exact
path='/admin/:name'
render={()=> <Admin />}
props={childProps}
/>
<Route path='/' render={props => <User {...props} />}/>
</Switch>
</div>
</Route>
</BrowserRouter>
</div>
</ApolloProvider>)
只有当您再次输入 URL 时,该路线才会再次呈现。您正在执行重定向,这意味着它在身份验证完成后将永远没有机会输入相同的 URL。您应该延迟呈现受保护的路由,直到您确认身份验证:
useEffect(() => {
async function onLoad() {
try {
let user = await Auth.currentSession();
userHasAuthenticated(!!user.accessToken.payload);
} catch (e) {
if (e !== 'No current user') {
alert(e);
}
}
}
onLoad();
}, []);
...
const ProtectedRoute = ({render: C, props: childProps, ...rest}) => {
if (childProps === null) {
// app still waiting authentication
return 'Loading...';
}
return (
<Route
{...rest}
render={rProps =>
(childProps) ? (
<C {...rProps} {...childProps} />
) : (
<Redirect
to={`/login?redirect=${rProps.location.pathname}${
rProps.location.search
}`}
/>
)
}
/>
);
}
我在我的项目中使用 aws-amplify、react-hook。该应用程序有一些私有路由已定义如下:
const ProtectedRoute = ({render: C, props: childProps, ...rest}) => {
return (
<Route
{...rest}
render={rProps =>
(childProps) ? (
<C {...rProps} {...childProps} />
) : (
<Redirect
to={`/login?redirect=${rProps.location.pathname}${
rProps.location.search
}`}
/>
)
}
/>
);
}
在App.js中,我们更改childProps来定义用户是否登录。但是当childProps改变时,Switch不会重新渲染。强制 React 重新渲染其路由的方法是什么,因为 isAuthenticated 已更改但 ProtectedRoute 未重新渲染。
const [isAuthenticated, userHasAuthenticated] = useState(null);
useEffect(() => {
onLoad();
}, []);
async function onLoad() {
try {
let user = await Auth.currentSession();
if (user.accessToken.payload) {
userHasAuthenticated(user.accessToken.payload);
}
} catch (e) {
if (e !== 'No current user') {
alert(e);
}
}
}
.....
const childProps = isAuthenticated;
return (
<ApolloProvider client={client} >
<div className="App">
<BrowserRouter>
<Route path='/'>
<div>
<Switch>
<Route path='/login' render={props => <Login {...props}/>} exact/>
<ProtectedRoute
exact
path='/admin/:name'
render={()=> <Admin />}
props={childProps}
/>
<Route path='/' render={props => <User {...props} />}/>
</Switch>
</div>
</Route>
</BrowserRouter>
</div>
</ApolloProvider>)
只有当您再次输入 URL 时,该路线才会再次呈现。您正在执行重定向,这意味着它在身份验证完成后将永远没有机会输入相同的 URL。您应该延迟呈现受保护的路由,直到您确认身份验证:
useEffect(() => {
async function onLoad() {
try {
let user = await Auth.currentSession();
userHasAuthenticated(!!user.accessToken.payload);
} catch (e) {
if (e !== 'No current user') {
alert(e);
}
}
}
onLoad();
}, []);
...
const ProtectedRoute = ({render: C, props: childProps, ...rest}) => {
if (childProps === null) {
// app still waiting authentication
return 'Loading...';
}
return (
<Route
{...rest}
render={rProps =>
(childProps) ? (
<C {...rProps} {...childProps} />
) : (
<Redirect
to={`/login?redirect=${rProps.location.pathname}${
rProps.location.search
}`}
/>
)
}
/>
);
}