Reactjs 关于未安装组件中设置状态的React警告

Reactjs 关于未安装组件中设置状态的React警告,reactjs,Reactjs,我得到了这个错误: 警告:js:33警告:无法在 未安装的组件。这是无操作,但表示内存泄漏 在您的应用程序中。若要修复,请取消所有订阅和异步 componentWillUnmount方法中的任务 但我没有使用componentWillUnMount方法 我使用HOC来确保用户在访问其/account路由之前经过身份验证 以下是路线: <StyleRoute props={this.props} path="/account" component= {RequireAuth(Account

我得到了这个错误:

警告:js:33警告:无法在 未安装的组件。这是无操作,但表示内存泄漏 在您的应用程序中。若要修复,请取消所有订阅和异步 componentWillUnmount方法中的任务

但我没有使用componentWillUnMount方法

我使用HOC来确保用户在访问其/account路由之前经过身份验证

以下是路线:

<StyleRoute props={this.props} path="/account" component= 
{RequireAuth(Account)} />

其中RequireAuth是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);
}
从“react router”导入{withRouter};
导出默认函数RequireAuth(组件){
返回类AuthenticatedComponent扩展了React.Component{
组件willmount(){
this.checkAuth();
}
checkAuth(){
如果(!this.props.isAuthenticated){
this.props.history.push(`/`);
}
}
render(){
返回此.props.isAuthenticated
? 
:null;
}
}
返回路由器(认证组件);
}
代码按预期工作,但在呈现/account时,我会遇到该错误。正如您所注意到的,在我的直接代码中没有componentWillUnMount方法。我真的很不明白为什么这个警告不断出现,任何信息都会有所帮助


更新日期:2018年5月23日:

为了消除错误并使道具得以传承,我做了两件事:

1) 我选择在父应用程序组件中使用两个高阶函数,而不是使用HOC。一个高阶函数用于传递道具,另一个用于检查身份验证。我在传递除浏览器历史记录以外的任何道具时遇到困难,因此下面的renderProps函数

renderProps = (Component, props) => {
  return (
      <Component {...props} />
    );
}

checkAuth = (Component, props) => {
    if (props.isAuthenticated) {
        return <Component {...props} />
    }
    if (!props.isAuthenticated) {
        return <Redirect to='/' />
    }
}
renderProps=(组件、道具)=>{
返回(
);
}
checkAuth=(组件、道具)=>{
如果(道具已验证){
返回
}
如果(!props.isAuthenticated){
返回
}
}
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} />
//我可以通过上面的函数传递道具来执行此操作
this.checkAuth(SitterDashboard,this.props)}/>
this.renderProps(用户,this.props)}/>
//我不能通过道具来做这件事
以下是关于路由器vs组件作为路由渲染方法的文档:

还有,这里有一个很好的解释

最后,我使用React Router 4文档中的这段代码作为我上面所做工作的模板。我确信下面的内容更清晰,但我仍在学习,我所做的对我来说更有意义

const PrivateRoute = ({ component: Component, ...rest }) => (
<Route
  {...rest}
  render={props =>
  fakeAuth.isAuthenticated ? (
       <Component {...props} />
      ) : (
        <Redirect
          to={{
            pathname: "/login",
            state: { from: props.location }
          }}
        />
      )
    }
  />
);
const PrivateRoute=({component:component,…rest})=>(
伪造的。是否已验证(
) : (
)
}
/>
);

我之前也有同样的错误,它是由使用ref标记的组件生成的,并且有一些手动操作

查看此类错误的一个好方法是绘制应用程序流,并查看何时调用
setState

如果我是你,我会改变的另一件事是
componentDidMount
而不是
componentWillMount
来检查一些数据。考虑到fb已弃用此功能

此生命周期以前命名为componentWillMount。该名称将继续使用到第17版。使用重命名不安全生命周期代码mod自动更新组件


我也遇到过类似的问题,但我确实找到了相同问题背后的原因,因此下面是我遇到此错误的代码片段

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”)解决了问题


我希望这有帮助

通过将ComponentWillMount更改为ComponentDidMount,您可以尝试同样的方法吗?我尝试过了,但它会抛出一个错误,因为它需要在呈现组件之前知道它们是否经过身份验证。好的,在这种情况下,您可以从那里删除history.push,并设置一个标志以显示其未经身份验证,并在未经身份验证的情况下返回render()。History.push将尝试卸载未安装的组件,因此出现错误。感谢帮助。正如React Router 4文档中提到的,我最终使用了render而不是component,错误消失了。这是什么意思?你能写一个简短的代码示例吗?我觉得医生谈论这件事毫无意义