React Router v5的问题

时间:2020-10-04 19:22:52

标签: reactjs react-redux react-router

我正在尝试在用户个人资料中显示一个设置页面,其中包含多个路由,例如“我的帐户”,“更改密码” ...)

/ settings页面的默认布局显示在/ settings上,但随后的页面(/ settings / account,/ settings / change-password)拒绝显示。我一直在尝试解决几个小时的问题,似乎无法提出解决方案...

Index.js

ReactDOM.render(
  <Provider store={store}>
    <ConnectedRouter history={history}>
      <App />
    </ConnectedRouter>
  </Provider>,
  document.getElementById('root')
);

App.js

function App() {
  const [loading, setLoading] = useState(true);
  const dispatch = useDispatch();

  useEffect(() => {
    dispatch(attemptGetUser())
      .then(() => setLoading(false))
      .catch(() => setLoading(false));
    // eslint-disable-next-line
  }, []);

  return loading ? (
    <Loading cover="page" />
  ) : (
    <div className="App">
      <Switch>
        <Route path="/" component={Views} />
      </Switch>
    </div>
  );
}

Views / index.js

export const Views = () => {
  return (
    <Switch>
      <Route exact path="/">
        <Redirect to="/dashboard" />
      </Route>
      <Route path="/auth">
        <AuthLayout />
      </Route>
      <Route path="/">
        <AppLayout />
      </Route>
    </Switch>
  );
};

export default withRouter(Views);

AppViews / index.js

const AppViews = ({ match }) => {
  return (
    <Suspense fallback={<Loading cover="content" />}>
      <Switch>
        <ProtectedRoute path={`/dashboard`} component={Dashboard} />
        <ProtectedRoute path={`/settings`} component={Settings} />
        <ProtectedRoute path={`/logout`} component={Logout} />
        <Redirect from={`${match.url}`} to={'/dashboard'} />
      </Switch>
    </Suspense>
  );
};

export default AppViews;

Settings / index.js

const SettingOption = ({ match, location }) => {
  return (
    <Menu
      defaultSelectedKeys={`${match.url}/account`}
      mode="inline"
      selectedKeys={[location.pathname]}
    >
      <Menu.Item key={`${match.url}/account`}>
        <UserOutlined />
        <span>My Account</span>
        <Link to={`account`} />
      </Menu.Item>
      <Menu.Item key={`${match.url}/change-password`}>
        <LockOutlined />
        <span>Change Password</span>
        <Link to={`change-password`} />
      </Menu.Item>
    </Menu>
  );
};

const SettingContent = ({ match }) => {
  return (
    <Switch>
      {/* <Redirect exact from={`${match.url}`} to={`${match.url}/account`} /> */}
      <Route path={`${match.url}/account`} component={EditProfile} />
      <Route path={`${match.url}/change-password`} component={ChangePassword} />
    </Switch>
  );
};

export class Setting extends Component {
  render() {
    return (
      <InnerAppLayout
        sideContentWidth={320}
        sideContent={<SettingOption {...this.props} />}
        mainContent={<SettingContent {...this.props} />}
      />
    );
  }
}

export default Setting;

受保护的路线

const ProtectedRoute = ({ path, component }) => {
  const { isAuth } = useSelector((state) => state.user);

  return isAuth ? (
    <Route path={path} exact component={component} />
  ) : (
    <Redirect to="/auth/login" />
  );
};

我们非常感谢您的帮助。 TIA!

1 个答案:

答案 0 :(得分:0)

您需要在exact的路线上使用AppViews/index.js

<ProtectedRoute exact path={`/settings`} component={Settings} />

,以及随后在Settings/index.js的路线

<Route exact path={`${match.url}/account`} component={EditProfile} />
<Route exact path={`${match.url}/change-password`} component={ChangePassword} />