最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • 学习记录-week2(React Router)

    正文概述 掘金(陀思妥郑夫斯基)   2021-01-07   513

    学习目标

    1. 单页应用是什么
    2. 前端路由是什么
    3. React-router 的简单使用

    单页应用

    在古老的 web 开发领域,从一个页面跳转到另一个页面,通常会从服务器重新请求对应的页面。比如,我们从一个购物网站的商品列表页 www.shop.com , 跳转到商品详情页 www.item.com 。 在访问 www.shop.com 时,会请求 shop.html 以及相应的资源,而在访问 www.item.com 时,会请求 item.html 以及相应的资源。这种页面之前的跳转以及资源请求,往往会给用户在页面之间的切换造成割裂感,带来不好的用户体验。而单页应用则是另外一种模型,它会通过访问不同的页面 url ,动态的重写当前页面,来实现页面之间的切换。也就是说,在单页应用的模式中,我们往往只是请求了一次 index.html 以及相应的资源,而页面之间的切换,往往是通过 js 的逻辑进行控制的

    现在常见的开发模式,一般是多页与单页共同使用。而更多的关于单页应用与多页应用的信息,优劣势比较,大家可以自行查阅资料。

    路由

    路由在不同的领域可能有不同的定义。但是在前端开发领域,我们可以简单的理解为,它是一种保证 url 和页面同步的技术。更进一步说,前端路由,是指保证我们在开发单页应用时,不同的 url 对应不同页面(组件)的技术。

    单页应用的 url 与页面同步

    打开我们之前的工程,在 src 目录下先建立一个 App.js(因为还没有学 ts ,所以先用 js 来写,下同)。

    假设我们拥有两个页面,商品列表页,和商品详情页,所以我们来声明下这两个组件:

    const Shop = () => {
      return <div>商品列表页</div>;
    };
    
    const ShopItem = () => {
      return <div>商品详情页</div>;
    };
    

    接着我们来写下页面的整体结构,有一个导航列表,点击对应的页面,跳转到对应的页面(此处我们采用哈希 hash 路由)。导航列表下面是对应的不同页面,默认为空。

    const App = () => {
      return (
        <div>
          <ul>
            <li><a href="#/shop">Shop</a></li>
            <li><a href="#/shop-item">ShopItem</a></li>
          </ul>
          {/* 此处放页面内容 */}
        </div>
      );
    };
    

    之后,我们需要:

    1. state 来记录当前页面的路由,当路由变化时,触发 App 的 re-render
    2. 页面内容根据当前的路由 state 来渲染不同的页面内容
    3. 在跳转到不同的路由时更改路由 state ,来保证路由 state 与 url 是同步的。这里有两种做法:
      1. 在跳转时将路由 state 更改(a 标签点击事件)
      2. 利用浏览器的 hashchange 事件,在对应的回调函数里更改 state

    这里我们选用第二种(监听 hashchange 事件)方法:

    const Page = ({ route }) => {
      if (route === '/shop') {
        return <Shop />;
      } else if (route==='/shop-item') {
        return <ShopItem />;
      }
      return null;
    };
    
    const App = () => {
      const [route, setRoute] = useState('');
    
      useEffect(() => {
        window.addEventListener('hashchange', () => {
          const r = window.location.hash.substr(1);
          setRoute(r);
        });
      }, []);
    
      return (
        <div>
          <ul>
            <li><a href="#/shop">Shop</a></li>
            <li><a href="#/shop-item">ShopItem</a></li>
          </ul>
          <Page route={route} />
        </div>
      );
    };
    

    之后,我们更改下入口文件 src/index.tsx 中的引用:

    + import App from './App';
    
    ReactDOM.render(
      <React.StrictMode>
    -   <div>123</div>
    +   <App />
      </React.StrictMode>,
      document.getElementById('root')
    );
    

    最后,我们npm start运行项目。

    如此一来,我们就实现了 url 与页面的同步。

    但是呢,上面的代码是有一些改进空间的。如果当路由多了之后,我们需要改动的地方有:

    1. APP 组件中的列表加入新的项目
    2. Page 组件中增加比较逻辑

    为了避免这种情况,造成的维护困难,我们是可以进一步分离出一个路由配置层的(虽然我们之后不大可能还是自己来实现路由,但是此处还是提供一种让代码更健壮的思路):

    // 我们将这个路由配置层,称为路由表 routes ,它是一个数组:
    const routes = [
      {
        path: '/shop',
        component: Shop,
        text: 'Shop',
      },
      {
        path: '/shop-item',
        component: ShopItem,
        text: 'ShopItem',
      }
    ];
    
    // 抽象一个由 path 获得 hash 路径的方法
    const getHashPath = (path) => {
      return `#${path}`;
    };
    
    const Page = ({ route }) => {
      // 将路由表,转换成一个路由表 map ,key 为 path ,value 为 path 对应的路由配置
      const routesMap = routes.reduce((res, route) => {
        const { path } = route;
        res[path] = route;
        return res;
      }, {});
      if (routesMap[route]) {
        const Route = routesMap[route].component;
        return <Route />;
      }
      return null;
    };
    
    ...
    <ul>
      {
        routes.map((route) => {
          const { path, text } = route;
          return (
            <li key={path}>
              <a href={getHashPath(path)}>{text}</a>
            </li>
          );
        })
      }
    </ul>
    ...
    

    之后,我们再添加路由时,只需要修改路由表即可。

    React Router

    因为我们选用的技术栈是 React ,而 React 周边生态中有一个非常好用并且广受欢迎的路由库,那就是 React Router。所以我们的路由库,自然就选用的是 React Router。

    因为 React Router 配置相关的内容比较多,虽然会简单的说一部分,但是更好的学习方式还是看文档:reactrouter.com/web/guides/…

    接着我们来简单过一下常用的几个组件:

    • <Router> 一个通用的路由器组件,来保持你的UI与URL同步
    • <BrowserRouter> 使用 HTML5 history API 的路由器组件
    • <HashRouter> 使用 url 中哈希部分 的路由器组件(不推荐使用了)
    • <Link> 导航组件
    • <Route> 当 url 路径与配置路径匹配时,呈现对应 UI 的组件
    • <Switch> 渲染第一个被 location 匹配到的子元素的 <Route> 或者 <Redirect>

    接下来是实战环节。

    首先,我们需要先安装 React Router :

    npm install react-router-dom
    

    接下来我们使用 React Router 配合 HTML5 history API 的形式,来改造下我们之前的例子:

    const App = () => {
      return (
        <div>
          <BrowserRouter>
            <ul>
              {
                routes.map((route) => {
                  const { path, text } = route;
                  return (
                    <li key={path}>
                      <Link to={path}>{text}</Link>
                    </li>
                  );
                })
              }
            </ul>
            <Switch>
              {
                routes.map((route) => {
                  const { path, component } = route;
                  return <Route key={path} path={path} component={component} exact />;
                })
              }
            </Switch>
          </BrowserRouter>
        </div>
      );
    };
    

    其中,我们删除了很多用来保持 url 与 组件匹配的代码,而是利用 React Router 配置来实现。

    结语

    好了,本期的内容到这里就差不多了,不算难,配置相关的内容会多一些。我个人除了常用的配置外,不是很推荐去死记硬背这些配置内容的,用的时候去翻下文档就好了。

    工程地址:github.com/VarHug/stud…


    起源地下载网 » 学习记录-week2(React Router)

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元