高阶组件会引发无效的反应元素误差(ReactJS)



所以我最近一直在阅读有关HOC的信息,并决定在我的应用程序中使用它们,以将授权逻辑传递给儿童组件。

我正在尝试通过HOC渲染<Route />组件,但它记录了错误:

未被发现的错误:authRoute(...):必须返回有效的反应元素(或null)。您可能已经返回了未定义的,一个数组或其他一些无效的对象。

这是HOC的代码:

const AuthRoute = ({ component: Component }) => {
  class AuthComponent extends Component {
    // Authorisation logic here
    render() {
      return (
          <Route render={props => <Component {...props}/>} />
      )
    }
  }
  return AuthComponent;
};

,然后我将此事件用作<Route />组件的别名:

<BrowserRouter>
  <AuthRoute path="/account" component={PrivateComponent} />
</BrowserRouter>

编辑:

但是这种方法正常:

const AuthRoute = ({ component: Component, ...rest }) => (
    <Route {...rest} render={props => (
      checkAuth() ? (<Component {...props}/>) : (<Redirect to={{pathname: '/', state: { from: props.location }}}/>)
    )}/>
);
<BrowserRouter>
  <AuthRoute path="/account" component={PrivateComponent} />
</BrowserRouter>

您需要查看架构。确实,您的方法是关于事件模式的完全矛盾的。您可能需要进行以下操作:

<BrowserRouter>
  <Route path="/account" component={AuthRoute(PrivateComponent)} />
</BrowserRouter>

如果您同意这种致电HOC的设计,则HOC实施将为:

const AuthRoute = (Composed) => {
  class AuthComponent extends React.Component {
    // Authorisation logic here
    componentWillMount() {
       if (!checkAuth()) {
         this.props.history.push({pathname: '/', state: { from: this.props.location }});
       }
    }
    render() {
      return (
          <Composed {...this.props} />
      )
    }
  }
  return AuthComponent;
};

在第一种情况下,您要返回类实例

const AuthRoute = ({ component: Component }) => {
  class AuthComponent extends Component {         
    // Authorisation logic here
    render() {
      return (
          <Route render={props => <Component {...props}/>} />
      )
    }
  }
  return AuthComponent;  // returning the class object here and not an instance 
};

因此,如果您想使用它,则需要写

<BrowserRouter>
  <Route path="/account" component={AuthRoute(PrivateComponent)} />
</BrowserRouter>

其中 AuthRoute(PrivateComponent)是类对象,路由在内部创建一个实例

但是,在第二种情况下,它不是HOC,而是返回有效的React元素的功能组件,

const AuthRoute = ({ component: Component, ...rest }) => (
    <Route {...rest} render={props => (
      checkAuth() ? (<Component {...props}/>) : (<Redirect to={{pathname: '/', state: { from: props.location }}}/>)
    )}/>
);

,因此

使用<AuthRoute path="/account" component={PrivateComponent} />,您调用了一个组件实例,该实例是功能组件收到Props pathcomponent

我对您写的语法并不熟悉。但是发现了一件事。您的参数是组件,但在您内部使用的组件,在此上下文中,该组件是未定义的

应该是:

const AuthRoute = (Component ) => { // <-- Component which refers to PrivateComponent
  class AuthComponent extends React.Component {  // <-- React.Component
     ....       

而不是:

const AuthRoute = ({ component: Component }) => {
    class AuthComponent extends Component { 
      ...

还请查看我的其他答案,使其具有优雅的事件。

最新更新