我收到此错误:
warning.js:33警告:无法调用setState(或forceUpdate) 未安装的组件。这是一个无操作,但它表示内存泄漏 在你的申请中。要修复,取消所有订阅和异步 componentWillUnmount方法中的任务。
但我没有使用componentWillUnMount方法。
我使用HOC确保用户在访问其/帐户路由之前已通过身份验证。
这是路线:
<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方法。我真的不知道为什么这个警告会突然出现,任何信息都会有所帮助。
更新5/23/18:
为了摆脱这个错误并仍然让道具传下来,我做了两件事:
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 }
}}
/>
)
}
/>
);
答案 0 :(得分:7)
我之前有同样的错误,它是由一个使用ref标签的组件生成的,并且有一些手动操作。
看到这类错误的好习惯是吸引您的应用流程,看看您何时致电setState
。
如果我是你,我会改变的另一件事是componentDidMount
而不是componentWillMount
来检查一些数据。考虑到fb已弃用此功能。
此生命周期以前名为componentWillMount。该名称将继续有效,直到版本17.使用rename-unsafe-lifecycles codemod自动更新组件。
答案 1 :(得分:2)
我有一个类似的问题,但是我确实弄清楚了这个问题的原因,所以这是我遇到此错误的代码片段。
Warning: Can't call setState (or forceUpdate) on an unmounted component. This is a no-op, but it indicates a memory leak in your application. To fix, cancel all subscriptions and asynchronous tasks in the componentWillUnmount method.
原因:
this.setState({ showLoader: true });
const { username } = this.state;
const URL = `https://api.github.com/users/${username}`;
try {
const { data } = await axios(URL);
this.props.apiData(data);
this.props.history.push("profile");
} catch (e) {
console.error(e);
}
this.setState({ showLoader: false });
如代码段所示,我在做
this.props.history.push("profile");
在设置状态之前。
this.setState({ showLoader: false });
然后在这种情况下 err 似乎是合法的,因为我将重定向到另一个组件,然后在我之前的组件上设置状态。
解决方案:
通过放置
this.setState({ showLoader: false });
this.props.history.push("profile");
上方的问题已解决。
我希望这会有所帮助。