【发布时间】:2018-10-06 08:31:35
【问题描述】:
我收到此错误:
warning.js:33 警告:不能调用 setState(或 forceUpdate) 未安装的组件。这是一个空操作,但它表示内存泄漏 在您的应用程序中。要修复,取消所有订阅和异步 componentWillUnmount 方法中的任务。
但我没有使用 componentWillUnMount 方法。
我正在使用 HOC 来确保用户在访问他们的 /account 路由之前已经过身份验证。
路线如下:
<StyleRoute props={this.props} path="/account" component=
{RequireAuth(Account)} />
其中 RequireAuth 是 HOC。这是 HOC:
import { withRouter } from 'react-router';
export default function RequireAuth(Component) {
return class AuthenticatedComponent extends React.Component {
componentWillMount() {
this.checkAuth();
}
checkAuth() {
if ( ! this.props.isAuthenticated) {
this.props.history.push(`/`);
}
}
render() {
return this.props.isAuthenticated
? <Component { ...this.props } />
: null;
}
}
return withRouter(AuthenticatedComponent);
}
代码按预期工作,但在呈现 /account 时出现该错误。如您所见,在我的直接代码中没有一个 componentWillUnMount 方法。我真的不知道为什么这个警告不断弹出,任何信息都会有所帮助。
2018 年 5 月 23 日更新:
为了摆脱错误并且仍然有 props 传递,我做了两件事:
1) 我选择在父 App 组件中拥有两个高阶函数,而不是使用 HOC。一个高阶函数是传递道具,另一个是检查身份验证。我在传递浏览器历史记录以外的任何道具时遇到了麻烦,因此下面的 renderProps 函数。
renderProps = (Component, props) => {
return (
<Component {...props} />
);
}
checkAuth = (Component, props) => {
if (props.isAuthenticated) {
return <Component {...props} />
}
if (!props.isAuthenticated) {
return <Redirect to='/' />
}
}
2) 要使用这些,我必须在我的路由中进行用户渲染,而不是组件。
//I could pass props doing this, sending them through the above functions
<Route exact path="/sitter-dashboard" render={ () => this.checkAuth(SitterDashboard, this.props) } />
<Route exact path={"/account/user"} render={() => this.renderProps(User, this.props)} />
//I couldn't pass props doing this
<Route {...this.props} exact path="/messages" component={Messages} />
这里是关于路由与组件作为路由渲染方法的文档:https://reacttraining.com/react-router/web/api/Route/route-render-methods
另外,这里有一个很好的解释 Stack Overflow
最后,我使用 React Router 4 文档中的这段代码作为我上面所做的模板。我确信下面的内容更干净,但我仍在学习,我所做的对我来说更有意义。
const PrivateRoute = ({ component: Component, ...rest }) => (
<Route
{...rest}
render={props =>
fakeAuth.isAuthenticated ? (
<Component {...props} />
) : (
<Redirect
to={{
pathname: "/login",
state: { from: props.location }
}}
/>
)
}
/>
);
【问题讨论】:
-
您可以通过将 ComponentWillMount 更改为 ComponentDidMount 来尝试相同的方法吗?
-
我做了,但它抛出了一个错误,因为它需要在渲染组件之前知道它们是否经过身份验证。
-
好的,在这种情况下,您可以从那里删除 history.push 并设置一个标志以显示其未经身份验证并在未经身份验证的情况下在 render() 中返回
。 histoty.push 将尝试卸载未安装的组件,因此出现错误。 -
感谢您的帮助。如 React Router 4 文档中所述,我最终使用渲染而不是组件,并且错误消失了。
-
那是什么意思?你能写一个你的代码的简短例子吗?我没有找到任何关于这个文档的观点
标签: reactjs