ReactJs:如何在道具更改时使根组件重新渲染
ReactJs: How to make root component rerender when a prop changes
我有这个管理通知的组件NotificationToast
。
当用户 已通过身份验证 时,我需要 始终呈现 。
所以这就是我所做的:
class App extends Component {
render() {
const state = store.getState();
const { isAuthenticated } = state.auth;
return (
<Provider store={store}>
<BrowserRouter basename="/">
<Switch>
<PublicRoute path="/register-page" component={RegisterPage} />
<PrivateRoute path="/profile-page" component={ProfilePage} />
<Redirect to="/home" />
</Switch>
{isAuthenticated && (
<div>
<NotificationToast />
</div>
)}
</BrowserRouter>
</Provider>
);
}
}
export default App;
问题是这在以下场景中不起作用:
- 用户尚未登录。
- 所以他没有通过身份验证。所以
state.auth.isAuthenticated
是 false
- 当他登录时,
state.auth.isAuthenticated
设置为 true
。
- 但是,问题是
App
未检测到此更改,因此不会重新呈现。
- 因此,
NotificationToast
不会被渲染。
- 因此通知系统不起作用。
这在用户登录后刷新页面时有效,因为state.auth.isAuthenticated
从一开始就是true
。
这是因为这段代码:
if (localStorage.jwtToken) {
// Set auth token header auth
setAuthToken(localStorage.jwtToken);
// Decode token and get user info and expiration
const decoded = jwt_decode(localStorage.jwtToken);
// Set User and is Authenticated
store.dispatch(setCurrentUser(decoded));
// Now if you reload a page, if the user has already logged-in you will still have his info in he state
store.dispatch(clearCurrentProfile());
// Check for expired token
const currentTime = Date.now() / 1000;
if (decoded.exp < currentTime) {
store.dispatch(logoutUser());
store.dispatch(clearCurrentProfile());
// Redirect to login
window.location.href = "/login";
}
}
它检查用户是否已经登录,如果他已经登录,则将 state.auth.isAuthenticated
设置为 true
。
有什么建议吗?
useStore 用于检索存储。但是这种存储访问只能用于存储操作,比如 reducer 替换。当存储改变时,以这种方式访问存储的组件不会更新。
请使用“useSelector”
const isAuthenticated = useSelector(state => state.auth)
我有这个管理通知的组件NotificationToast
。
当用户 已通过身份验证 时,我需要 始终呈现 。
所以这就是我所做的:
class App extends Component {
render() {
const state = store.getState();
const { isAuthenticated } = state.auth;
return (
<Provider store={store}>
<BrowserRouter basename="/">
<Switch>
<PublicRoute path="/register-page" component={RegisterPage} />
<PrivateRoute path="/profile-page" component={ProfilePage} />
<Redirect to="/home" />
</Switch>
{isAuthenticated && (
<div>
<NotificationToast />
</div>
)}
</BrowserRouter>
</Provider>
);
}
}
export default App;
问题是这在以下场景中不起作用:
- 用户尚未登录。
- 所以他没有通过身份验证。所以
state.auth.isAuthenticated
是false
- 当他登录时,
state.auth.isAuthenticated
设置为true
。 - 但是,问题是
App
未检测到此更改,因此不会重新呈现。 - 因此,
NotificationToast
不会被渲染。 - 因此通知系统不起作用。
这在用户登录后刷新页面时有效,因为state.auth.isAuthenticated
从一开始就是true
。
这是因为这段代码:
if (localStorage.jwtToken) {
// Set auth token header auth
setAuthToken(localStorage.jwtToken);
// Decode token and get user info and expiration
const decoded = jwt_decode(localStorage.jwtToken);
// Set User and is Authenticated
store.dispatch(setCurrentUser(decoded));
// Now if you reload a page, if the user has already logged-in you will still have his info in he state
store.dispatch(clearCurrentProfile());
// Check for expired token
const currentTime = Date.now() / 1000;
if (decoded.exp < currentTime) {
store.dispatch(logoutUser());
store.dispatch(clearCurrentProfile());
// Redirect to login
window.location.href = "/login";
}
}
它检查用户是否已经登录,如果他已经登录,则将 state.auth.isAuthenticated
设置为 true
。
有什么建议吗?
useStore 用于检索存储。但是这种存储访问只能用于存储操作,比如 reducer 替换。当存储改变时,以这种方式访问存储的组件不会更新。
请使用“useSelector”
const isAuthenticated = useSelector(state => state.auth)