React项目生成路由

React项目生成路由

使用React-Router完成路由跳转

项目需要加入页面路由,具体需求是,点击左侧菜单栏的选项,在右侧空白部分根据路由渲染不同组件,并支持动态嵌套路由。

踩了一些坑,在一番尝试后完成,在此记录

完整项目demo放在了github上 github.com/bupt-yanch/Router-demo

一. 基本原理

  1. 注册路由以及对应组件。比如这里注册了四种不同的组件 exact表示精准路由匹配
   <Router>
       <Route path="/" exact component={Home}/>
       <Route path="/smile" exact component={Smile}/>
       <Route path="/settings" exact component={Settings}/>
       <Route path="/settings/:id" exact component={RandomShow}/>
   </Router>
  1. 在想要跳转的地方选用不同方法进行跳转
如果不带参数跳转,比如点击菜单选项,使用<Link/>进行跳转
<Menu defaultSelectedKeys={['1']} >
    <Menu.Item key='1' icon={<HomeOutlined/>}>
        Home
        <Link to="/"/>
    </Menu.Item>
    <Menu.Item key='2' icon={<SmileOutlined/>}>
        Smile
        <Link to="/smile"/>
    </Menu.Item>
    <Menu.Item key='3' icon={<SettingFilled/>}>
        Settings
        <Link to="/settings"/>
    </Menu.Item>
</Menu>

如果需要带参数进行跳转,就使用如下方法,被<HushRouter>包含的所有子组件可以调用this.props.history

const rand = Math.random();
this.props.history.push({
    pathname: `/settings/${rand}`,
    state: {
        str: 'hello rand:',
        rand: rand,
    }
})

二. 根据历史记录正确选择Menu的Key

如果不做这个功能,在回退的时候,有可能路由和左侧菜单栏是不对应的。比如路由变为'/smile'的时候,左侧菜单栏高亮的选项还是Settings。

因为在回退的过程中,路由改变了,但Menu的key没改变。所以需要根据历史记录,监听其路由变化,并实时改变Menu的Key。

1. 添加state.menuKey
    state = {
        menuKey: ['1'],
    };
2. 添加监听,并根据前缀匹配,更新state
    componentDidMount() {
      this.props.history.listen(route => {
          const pathName = route.pathname;
          console.log(pathName)
          let key = '1';
          if (pathName.startsWith("/smile")) {
              key = '2';
          } else if (pathName.startsWith("/settings")) {
              key = '3';
          }
          this.setState({
              menuKey: [key]
          })
      })
  }
3. 设置Menu的key和state.menuKey关联
    <Menu theme="dark" 
        defaultSelectedKeys={['1']} 
        mode="inline" 
        selectedKeys={this.state.menuKey}
    >

三. 效果展示

启动服务后,默认渲染路由为 '/' 的组件

点击左侧不同的菜单Item,可以发现路由和右侧渲染内容都发生了改变

Settings组件中渲染的内容包括一个Button,是为了验证简单的嵌套路由。

点击这个按钮,会生成一个随机数,并在重定向到新路由时,将随机数加入新路由的路径中,且作为props传入新渲染的组件中

多次点击按钮,可以看到每次生成的随机数不同,对应的路由和渲染的内容不同

四. 后续优化

  1. 在使用动态路由后,路由传参跳转后刷新页面会导致白屏(参数消失,无法正常渲染)。参考了 博客链接 之后使用sessionStorage存储参数解决了这个问题。需要注意的是,如果传的参数是一个Json对象的话,需要转成String存,然后获取的时候parse,否则会无法正常存取。
// 比如某个组件的渲染就依赖跳转时传递的参数对象object,就可以如下编写
componentWillMount() {
  const {location} = this.props;
  let recvObject;
  if (location.state && location.state.experiment) {
      recvObject = location.state.object;
      sessionStorage.setItem('object', JSON.stringify(recvObject));
  } else {
      recvObject = JSON.parse(sessionStorage.getItem('object'));
  }
  this.setState({
      object: recvObject,
  });
}
posted @ 2021-03-25 13:01  BuptWade  阅读(425)  评论(0)    收藏  举报