React路由

436 阅读5分钟

react-router-dom6

一、React Router以三个包发布到npm

  • react-router:路由库的核心
  • react-router-dom:专门的router的dom(eg:BrowserRouter) && react-router
  • react-router-native:添加了ReactNative的API(eg:NativeRouter) && react-router

二、Component

1、BrowserRouter

 <BrowserRouter> 用于包裹整个应用。历史路由

2、HashRouter

 <HashRouter> 用于包裹整个应用。和hash路由

3、 <Routes/> <Route/> 

  • v6版本中移除了先前的<Switch>,引入了新的替代者:<Routes>
  • <Routes> <Route>要配合使用,且必须要用<Routes>包裹<Route>
  • <Route> 相当于一个 if 语句,如果其路径与当前 URL 匹配,则呈现其对应的组件。
  • <Route caseSensitive> 属性用于指定:匹配时是否区分大小写(默认为 false)。
  • 当URL发生变化时,<Routes>都会查看其所有子<Route> 元素以找到最佳匹配并呈现组件 。
  • <Route> 也可以嵌套使用,且可配合useRoutes()配置 “路由表” ,但需要通过<Outlet>组件来渲染其子路由。

4、 <Link> 

  1. 作用: 修改URL,且不发送网络请求(路由链接)。
  2. 注意: 外侧需要用 <BrowserRouter> 或 <HashRouter> 包裹。

5、  <NavLink> 

  1. 作用: 与 <Link> 组件类似,且可实现导航的“高亮”效果。

6、  <Navigate> 

  1. 作用:只要 <Navigate> 组件被渲染,就会修改路径,切换视图。
  2.  replace 属性用于控制跳转模式(push 或 replace,默认是push)。

7、 <Outlet> 

  1. 当 <Route> 产生嵌套时,渲染其对应的后续子路由。

三、hooks

1、 useRoutes()

作用:根据路由表,动态创建 <Routes> 和 <Route> 

2、useNavigate()

返回一个函数用来实现编程式导航。

const navigate = useNavigate()
const handle = () => {
    //第一种使用方式:指定具体的路径
    navigate('/login', {
      replace: false,
      state: {a:1, b:2}
    }) 
    //第二种使用方式:传入数值进行前进或后退,类似于5.x中的 history.go()方法
    navigate(-1)
  }

3、useParams()

回当前匹配路由的 params 参数,类似于5.x中的 match.params 。

获取动态路由的路径参数如"/useNavigate/:path"中的path

4、useSearchParams()

searchParams即urlquery的参数

  1. 作用:用于读取和修改当前位置的 URL 中的查询字符串。
  2. 返回一个包含两个值的数组,内容分别为:当前的seaech参数、更新search的函数。
    const [search, setSearch] = useSearchParams();
    const id = search.get("id");
// *************************************
    setSearch("id=4");

5、useLocation()

获取当前 location 信息,对标5.x中的路由组件的 location 属性。

    const location = useLocation();
    console.log(
        "🚀 ~ file: UseNavigate.tsx ~ line 20 ~ UseNavigate ~ location",
        location
    );
{
    "pathname": "/useNavigate/a",
    "search": "?id=3",
    "hash": "",
    "state": null,
    "key": "5pgw82ky"
}

 6、useMatch()

作用:返回当前匹配信息,对标5.x中的路由组件的 match 属性。

// http://localhost:3000/useNavigate/a?id=3

    const match = useMatch("/:x/:y");
    console.log(
        "🚀 ~ file: UseNavigate.tsx ~ line 28 ~ UseNavigate ~ match",
        match
    );
    
    
{
    "params": {
        "x": "useNavigate",
        "y": "a"
    },
    "pathname": "/useNavigate/a",
    "pathnameBase": "/useNavigate/a",
    "pattern": {
        "path": "/:x/:y",
        "caseSensitive": false,
        "end": true
    }
}

7、useInRouterContext()

作用:如果组件在  <Router>  的上下文中呈现,则  useInRouterContext  钩子返回 true,否则返回 false。

8、useNavigationType()

  1. 作用:返回当前的导航类型(用户是如何来到当前页面的)。
  2. 返回值: POP 、 PUSH 、 REPLACE 。
  3. 备注: POP 是指在浏览器中直接打开了这个路由组件(刷新页面)。

9、useOutlet()

  1. 作用:用来呈现当前组件中渲染的嵌套路由。

10、useResolvedPath()

  1. 作用:给定一个 URL值,解析其中的:path、search、hash值。
    const resolvedPath = useResolvedPath("/user?id=001&name=tom#qws");
    console.log(
        "🚀 ~ file: UseNavigate.tsx ~ line 55 ~ UseNavigate ~ resolvedPath",
        resolvedPath
    );
    
    
{
    "pathname": "/user",
    "search": "?id=001&name=tom",
    "hash": "#qws"
}

react-router-dom5

一、react-router-dom的理解

  • 是一个react的插件库
  • 目的是专门实现一个SPA的应用

二、基本使用

  • 定义好界面的导航区和展示区
  • 将导航区的a标签改为Link标签,从而实现路由变更
  • 展示区通过Router标签进行匹配,从而实现根据路由变更内容
  • 在App标签最外层添加BrowswerRouter或HashRouter

三、component

1、BrowserRouter历史模式(Browser为浏览器)

历史模式没有#号

2、HashRouter hash模式

hash模式带#号

3、link

当使用路由时不可能让用户自己到地址栏中去输入地址,因此使用点击链接的方式。

function App() {
  return (
    <div className="App">
      <div>
        <Link to="/home">点我去home</Link>
        <Link to="/user">点我去user</Link>
      </div>
      <Route path="/home" component={Home}/>
      <Route path="/user" component={User}/>
    </div>
  );
}
export default App;

4、NavLink

和 Link 的用法一致,但会在组件中增加 class="active",而后可以自行对该 class 进行编辑,达到点击后样式的控制。

exact模糊匹配

添加exact属性,模糊匹配

当设置了相同路由使用switch。

function App() {
  return (
    <div className="App">
      <div>
        <Link to="/home">点我去home</Link>
        <Link to="/user">点我去user</Link>
      </div>
      <Switch>
        <Route path="/" exact component={Home}/>
        <Route path="/home" component={Home}/>
        <Route path="/user" component={User}/>
      </Switch>
    </div>
  );
}
export default App;

5、switch

无switch时匹配到path会继续向下匹配,直到匹配完全,加了switch匹配一次就不会继续向下匹配

<Switch>
        <Route path="/" exact component={Home}/>
        <Route path="/home" component={Home}/>
        <Route path="/user" component={User}/>
</Switch>

四、高级

1、withRouter

withRoter相当于在组件的peops中注入了history、location、location对象

{
    "history": {
        "length": 37,
        "action": "POP",
        "location": {
            "pathname": "/Route/RouterDom5/a",
            "search": "?id=3",
            "hash": "",
            "key": "2445peds"
        }
    },
    "location": {
        "pathname": "/Route/RouterDom5/a",
        "search": "?id=3",
        "hash": "",
        "key": "2445peds"
    },
    "location": {
        "path": "/",
        "url": "/",
        "params": {},
        "isExact": false
    }
}

该组件由于要使用路由需要包裹在或中

eg:

function child(props: any) {
    console.log(props);
    return (
        <>
            <Link to="/Route/RouterDom6/a?id=3">点我去/</Link>
            <div>child</div>
        </>
    );
}
const Child = withRouter(child);
const RouterDom5 = () => {
    return (
        <>
            <div>v5</div>
            <BrowserRouter>
                <Child />
            </BrowserRouter>
        </>
    );
};

2、监控路由变化

通过props.history.listen函数监听

props.history.listen((link: any) => {
        console.log(link);
    });

3、编程式导航

通过props.history.push函数跳转

props.history.push("/home")

4、params 路由传参

params 方式进行传参

  • 需要在路由规则中设置传递的接受参数
  • 发送参数,直接在跳转路径后进行编写
  • 接受props.match.params.参数名

优势:刷新地址,参数依然存在

缺点:只能传递字符串,并且参数过多时url会变得丑陋。

<Route path="/home/:id" component={Home}/>

使用props.match.params接受参数

5、query 路由传参

query 方式进行传参

  • 不需要在路由规则中进行传递参数的配置
  • 直接发送数据
  • 使用 this.props.location.query.xxx

使用props.location.query接受参数

对比

v5主要是使用withRouter()注入组件相关参数,使用listen、push等进行监听和路由操作,使用props.match.params和props.location.query接受参数

v6使用useParams()获取路由中params参数,useSearchParams()获取query参数