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/ 本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接。
  • 相关阅读:
    不务正业系列-浅谈《过气堡垒》,一个RTS玩家的视角
    [LeetCode] 54. Spiral Matrix
    [LeetCode] 40. Combination Sum II
    138. Copy List with Random Pointer
    310. Minimum Height Trees
    4. Median of Two Sorted Arrays
    153. Find Minimum in Rotated Sorted Array
    33. Search in Rotated Sorted Array
    35. Search Insert Position
    278. First Bad Version
  • 原文地址:https://www.cnblogs.com/lightsong/p/15491449.html
Copyright © 2011-2022 走看看