我正在使用HOC组件来限制对未登录用户的路由访问。当从URL直接访问此路由时(在应用程序首次加载时),此HOC在安装或重新呈现时重新安装子组件的问题。例如,我在did mount
组件中有3次PaperWorkProgress
。
路线定义:
<Route path="/paperwork/progress" component={RequireAuth(PaperWorkProgress)}/>
这里有HOC代码:
import React, {Component} from 'react';
import {connect} from 'react-redux';
export default function(ComposedComponent) {
class Authentication extends Component {
// check if token exists in storage
componentWillMount() {
const token = localStorage.getItem('token');
if (!token) {
const {pathname, search} = this.props.location;
this.props.history.push({
pathname: '/signin',
search: `?redirect_to=${pathname}${search}`,
});
}
}
// additional check
componentWillUpdate(nextProps) {
if (!nextProps.loggedIn) {
const {pathname, search} = this.props.location;
this.props.history.push({
pathname: '/signin',
search: `?redirect_to=${pathname}${search}`,
});
}
}
render() {
return <ComposedComponent {...this.props} />;
}
}
function mapStateToProps(state) {
return {loggedIn: state.session.loggedIn};
}
return connect(mapStateToProps)(Authentication);
}
有什么想法吗?
答案 0 :(得分:2)
这个问题可能已经有一段时间了,但是我刚刚遇到了同样的问题。
最后,我发现我的 HOC函数实际上是在每次路线更改时调用的。
对我有用的是初始化时仅创建授权组件一次:
const AuthorisedDashboard = requireLogin(Dashboard);
然后再使用
<Route path="/dashboard" component={AuthorisedDashboard} />
或者,您知道,如果仅在授权模式下使用过,则可以导出已应用HOC功能的组件。
答案 1 :(得分:0)
我不确定这会对重新渲染问题产生影响,但您的代码感觉不对。
首先,你似乎有两个真实来源,你的redux商店和localStorage,这使事情变得复杂。如果要从以前的导航信息“保湿”商店,则应使用createStore“preloadedState”参数,而不是每次在组件中进行检查。 Cf Redux doc以及来自Redux自己Video for persisting and rehydrating State创作者的视频。一旦您的状态仅来自您的商店,它就会变得更加简单。
其次,
当您推送到组件内部的历史对象时,感觉就像您正在改变组件自己的道具(因为历史是道具)。这对我来说很奇怪,可能是你问题的根源。
为什么不在渲染方法中使用重定向组件呢? cf React router docs。该组件看起来像这样(显然你也需要更改你的登录组件,就像在文档中一样)
import React, { Component } from "react";
import { connect } from "react-redux";
import { Redirect } from "react-router-dom";
export default function(ComposedComponent) {
class Authentication extends Component {
render() {
return !this.props.loggedIn ? (
<Redirect
to={{
pathname: "/login",
state: { from: this.props.location }
}}
{...this.props}
/>
) : (
<ComposedComponent {...this.props} />
);
}
}
function mapStateToProps(state, ownProps) {
return { loggedIn: state.session.loggedIn, ...ownProps };
}
return connect(mapStateToProps)(Authentication);
}