zoukankan      html  css  js  c++  java
  • React-Router 非Route监管组件如何监听location变化?

    react-router-dom

    https://github.com/remix-run/react-router/blob/main/docs/getting-started/tutorial.md

    对于location的变化, 不论是 hashtag方式, 或者是 通过pushstate改变urlpath 的方式,

    这种情况下, 只有使用 Route 方式的 引用的 组件, 才能感知 路径变化(location对象), 加载此组件。

    import { render } from "react-dom";
    import {
      BrowserRouter,
      Routes,
      Route
    } from "react-router-dom";
    import App from "./App";
    import Expenses from "./routes/expenses";
    import Invoices from "./routes/invoices";
    
    const rootElement = document.getElementById("root");
    render(
      <BrowserRouter>
        <Routes>
          <Route path="/" element={<App />} />
          <Route path="expenses" element={<Expenses />} />
          <Route path="invoices" element={<Invoices />} />
        </Routes>
      </BrowserRouter>,
      rootElement
    );

    例如:

    https://reactrouter.com/web/api/history/history-is-mutable

    Route引用的组件 Comp 中能够在props中拿到 location 对象。

    The history object is mutable. Therefore it is recommended to access the location from the render props of <Route>, not from history.location. This ensures your assumptions about React are correct in lifecycle hooks. For example:

    class Comp extends React.Component {
      componentDidUpdate(prevProps) {
        // will be true
        const locationChanged =
          this.props.location !== prevProps.location;
    
        // INCORRECT, will *always* be false because history is mutable.
        const locationChanged =
          this.props.history.location !== prevProps.history.location;
      }
    }
    
    <Route component={Comp} />;

    Router模式

    BrowserRouter

    https://reactrouter.com/web/api/BrowserRouter

    A <Router> that uses the HTML5 history API (pushState, replaceState and the popstate event) to keep your UI in sync with the URL.

    <BrowserRouter
      basename={optionalString}
      forceRefresh={optionalBool}
      getUserConfirmation={optionalFunc}
      keyLength={optionalNumber}
    >
      <App />
    </BrowserRouter>

    https://javascript.ruanyifeng.com/bom/history.html#toc6

    var stateObj = { foo: 'bar' };
    history.pushState(stateObj, 'page 2', '2.html');

    HashRouter

    https://reactrouter.com/web/api/HashRouter

    A <Router> that uses the hash portion of the URL (i.e. window.location.hash) to keep your UI in sync with the URL.

    <HashRouter
      basename={optionalString}
      getUserConfirmation={optionalFunc}
      hashType={optionalString}
    >
      <App />
    </HashRouter>

    https://www.cnblogs.com/xiaonian8/p/13764821.html

    componentDidMount(){
      window.addEventListener('hashchange', this.routerEvent);
    }
    componentWillUnmount(){
      window.removeEventListener('hashchange',this.routerEvent);
    }
    
    routerEvent = (e)=>{
      // e.target.location.hash.replace("#","")
      // 去掉#就能获取即将跳转的那个路由的url了
    }

    问题:对于非Route引用的组件是否也能感知location变化?

    答案是肯定的:

    https://reactrouter.com/web/api/location

    location数据结构:

    {
      key: 'ac3df4', // not with HashHistory!
      pathname: '/somewhere',
      search: '?some=search-string',
      hash: '#howdy',
      state: {
        [userDefined]: true
      }
    }

    如下四种情况, 可以使用感知location变化。

    The router will provide you with a location object in a few places:

    使用withRouter给非Route控制组件,添加location监测能力

    https://reactrouter.com/web/api/withRouter

    对于定义的组件, 使用withRouter对其进行包裹,生成新的组件。

    You can get access to the history object’s properties and the closest <Route>'s match via the withRouter higher-order component. withRouter will pass updated match, location, and history props to the wrapped component whenever it renders.

    import React from "react";
    import PropTypes from "prop-types";
    import { withRouter } from "react-router";
    
    // A simple component that shows the pathname of the current location
    class ShowTheLocation extends React.Component {
      static propTypes = {
        match: PropTypes.object.isRequired,
        location: PropTypes.object.isRequired,
        history: PropTypes.object.isRequired
      };
    
      render() {
        const { match, location, history } = this.props;
    
        return <div>You are now at {location.pathname}</div>;
      }
    }
    
    // Create a new component that is "connected" (to borrow redux
    // terminology) to the router.
    const ShowTheLocationWithRouter = withRouter(ShowTheLocation);

    在组件中监听 pushState 引起的路径变化

    https://www.cnblogs.com/xiaonian8/p/13764821.html

    react router自带的history.listen

    let UNLISTEN;
    class Client extends React.Component {
      ...,
      componentDidMount(){
        // UNLISTEN变量用来接收解绑函数
        UNLISTEN = this.props.history.listen(route => { 
          console.log(route); 
        });
      }
      componentWillUnmount(){
        UNLISTEN && UNLISTEN(); // 执行解绑
      }
    }
    出处:http://www.cnblogs.com/lightsong/ 本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接。
  • 相关阅读:
    datagrid表格宽度设置成100%,宽度却不是100%,反而很窄
    Spring MVC 和Struts2对比
    在不知道用户名密码的情况下登录oracle数据库
    IE浏览器的兼容性问题
    在spring mvc 中读取配置文件(porperties)的信息
    godaddy设置方法 控制面板
    easyui datagrid 动态改变大小
    15 个最佳 jQuery 翻书效果插件
    windows7 如何关闭开机启动讲述人
    存储过程代码审核
  • 原文地址:https://www.cnblogs.com/lightsong/p/15491449.html
Copyright © 2011-2022 走看看