首页 > 解决方案 > 无法将“已连接”的 HOC 与反应路由器一起使用

问题描述

我正在制作一个 HOC,我可以使用它来确保登录的用户不会访问某些路线(我称之为“访客路线”)。它将连接到我的 redux 存储以访问用户的loggedIn状态。这是我对 HOC 的实现:

import React, { Component } from 'react';
import { connect } from 'react-redux';

export function guestRoute(ComposedComponent) {
  class GuestRoute extends Component {
    componentWillMount() {
      if (this.props.loggedIn) {
        this.props.router.push('/')
      }
    }

    componentWillUpdate() {
      if (this.props.loggedIn) {
        this.props.router.push('/')
      }
    }

    render() {
      return (
        <ComposedComponent {...this.props} />
      );
    }
  }

  const mapStateToProps = (state) => {
    const { loggedIn } = state.auth;
    return { loggedIn };
  };

  return connect(mapStateToProps)(GuestRoute);
}

如您所见,我正在返回一个“已连接”的包装组件。

这是我的路线以及如何使用此 HOC:

import React from 'react';
import { Route } from 'react-router';
import { guestRoute } from './routes/guestRoute';
import Main from './layout/Main';
import Signup from './auth/Signup';

const routes = (
  <Route component={Main}>
    <Route path="/signup" component={guestRoute(Signup)} />
  </Route>
);

export default routes;

这给了我两个错误:

Warning: Failed prop type: Invalid prop `component` supplied to `Route`.

Warning: React.createElement: type is invalid -- expected a string (for built-in components) or a class/function (for composite components) but got: symbol.

如何返回一个可以在我的路由中使用的有效组件,而不是返回的内容connect

编辑:我正在使用 react v16.13.1 和 react-router v3.2.1

这是一个重现错误的沙箱: https ://codesandbox.io/s/zealous-austin-vy2et?file=/src/store.js

标签: reactjsreact-reduxreact-router

解决方案


我让你的代码箱工作了,我做的主要事情是将 react-router 更新到最新的 react-router-dom。我不确定您为什么要使用带有古老路由器库的新项目。

我做的其他事情是让代码运行,我是否让应用程序声明成为一个实际组件而不是导致问题的静态 JSX

const App = () => (
  <React.StrictMode>
    <Provider store={store}>
      <Router>{routes}</Router>
    </Provider>
  </React.StrictMode>
);

ReactDOM.render(<App />, document.getElementById("root"));

我还使您的路线在声明方面有所不同,因为路线不同时支持子项和组件。由于 Main 中不需要 Route 值,因此可以将其更改为路由的子级。

const routes = (
  <>
    <Route path="/">
      <Main>
        <Route path="/signup" component={Signup} />
      </Main>
    </Route>
  </>
);

在 Guest Route 中,我更改了componentWillMountcomponentWillUpdateto componentDidMountcomponentDidUpdate因为它们是首选选项,因为其他选项现已弃用。

在注册中,我将它与周围的 guestRoute HOC 一起导出

export default guestRoute(
  connect(
    null,
    mapDispatchToProps
  )(Signup)
);

https://codesandbox.io/s/inspiring-field-yokx4?file=/src/layout/Main.jsx


推荐阅读