react-router

一、react-router是什么

react-router是一个用于管理React应用程序中路由的库。路由是指确定应用程序如何根据URL路径来渲染不同的组件和页面。使用react-router可以将应用程序的不同页面映射到不同的URL路径,以及在用户导航时动态地加载适当的组件。这样,用户在浏览应用程序时可以通过URL直接访问不同的页面,并且可以使用浏览器的后退和前进按钮进行导航。react-router提供了路由组件、链接组件和路由控制方式等功能,使得在React应用程序中实现路由功能更加方便和灵活。

二、基本用法

React Router 是一个用于在React应用中实现路由功能的库。它可以让我们在不刷新页面的情况下,通过改变URL路径来加载不同的组件,实现单页应用(SPA)的路由功能。

下面是一个基本的示例,展示了如何使用React Router来设置路由和渲染不同的组件。

首先,安装React Router库:

npm install react-router-dom

然后,在你的React组件中导入所需的模块:

import React from 'react';
import { BrowserRouter as Router, Route, Link } from 'react-router-dom';

接下来,在你的应用中定义一些组件:

const Home = () => (<div><h2>Home</h2></div>
);const About = () => (<div><h2>About</h2></div>
);const Contact = () => (<div><h2>Contact</h2></div>
);

然后,在你的渲染函数中使用 Router 组件来定义你的路由:

const App = () => (<Router><div><nav><ul><li><Link to="/">Home</Link></li><li><Link to="/about">About</Link></li><li><Link to="/contact">Contact</Link></li></ul></nav><Route exact path="/" component={Home} /><Route path="/about" component={About} /><Route path="/contact" component={Contact} /></div></Router>
);

这个示例中,我们在 nav 元素中定义了一些链接,分别指向不同路径,然后在 Route 组件中定义了与每个路径匹配时要渲染的组件。

最后,将 App 组件渲染到你的页面中:

ReactDOM.render(<App />, document.getElementById('root'));

现在,当你点击链接时,URL路径将随之改变,同时对应组件的内容也会被渲染到页面上。举个例子,点击 "About"链接将在页面上显示 “About” 组件的内容。

三、Link,Route

1. 基本使用

在React Router中,<Link><Route>是两个重要的组件,用于实现单页应用中的导航和路由。

<Link>组件是用于在页面中生成链接的组件。它类似于HTML中的<a>标签,但是在React Router中,使用<Link>组件能够实现类似页面跳转效果,而不需要重新加载整个页面。通过使用<Link>组件,可以指定链接的路径,并且在点击链接时,页面会更新并显示相应的组件内容,而不会导致整个页面的刷新。例如:

import { Link } from 'react-router-dom';function MyComponent() {return (<div><Link to="/home">Go to Home</Link></div>);
}

在上面的示例中,当点击"Go to Home"链接时,页面会导航到"/home"路径,并显示与"/home"路径匹配的组件内容。

<Route>组件则用于定义路径与组件的对应关系。它会根据当前URL路径来选择渲染哪个组件。每一个<Route>组件都有一个path属性,用于指定路径,以及一个component属性,用于指定渲染的组件。当URL路径与<Route>组件的path属性匹配时,将会渲染该<Route>组件的component属性中指定的组件。例如:

import { Route } from 'react-router-dom';function MyComponent() {return (<div><Route path="/home" component={Home} /></div>);
}

上面的示例中,当URL路径为"/home"时,将会渲染Home组件。

需要注意的是,<Route>组件通常被嵌套在一个根组件内部,以便在整个应用中进行路由的管理。可以使用Switch组件来包裹多个<Route>组件,并且只渲染路径与当前URL匹配的第一个<Route>组件。这样可以避免多个路由同时匹配到URL路径的情况。

2. exact

在react-router中,标签用于定义路由匹配规则。exact属性用于确保路由路径与当前URL完全匹配时才渲染组件。如果没有exact属性,当URL包含指定路径以及其他内容时,也会渲染对应的组件。

举个例子,假设我们有两个标签:

<Route path="/" component={Home} />
<Route path="/about" component={About} />

如果没有exact属性,当URL为"/about/contact"时,即使路径中包含了"/about",组件也会被渲染。但是如果添加了exact属性:

<Route exact path="/" component={Home} />
<Route exact path="/about" component={About} />

这样,当URL为"/about/contact"时,组件不会被渲染,因为路径不完全匹配。

使用exact属性可以确保只有当URL与路径完全匹配时才渲染组件,可以避免多个路由匹配的情况发生,提高路由的准确性和匹配的效率。

3. <Link><NavLink>

在React-Router中,<Link><NavLink>都是用于创建导航链接的组件,但它们有一些区别。

  1. activeClassName/activeStyle:

    • <NavLink>组件具有activeClassName和activeStyle属性,它们可以在链接被激活时为其添加自定义的类名或样式。
    • 举例:<NavLink to="/home" activeClassName="active">Home</NavLink>
  2. isActive:

    • <NavLink>组件还具有isActive属性,它可以用于自定义判断链接是否被激活的逻辑。
    • 举例:<NavLink to="/about" isActive={isActiveFunc}>About</NavLink>
  3. exact:

    • 当设置exact={true}时,<NavLink>只有在URL与其to属性完全匹配时才会被视为激活状态。
    • 举例:<NavLink to="/" exact>Home</NavLink>

综上所述,<Link>组件可以用于简单的导航链接,而<NavLink>组件具有更多的特性以及自定义激活状态样式的能力。

四、Switch

在React Router中,<Switch>组件用于确保只渲染与当前位置的URL匹配的第一个子组件,其他子组件将被忽略。它可以用来实现路由的匹配优先级,以及防止多个路由同时被渲染的问题。

<Switch>组件的作用如下:

  1. 只渲染与当前URL匹配的第一个<Route><Redirect>组件,忽略其他组件。
  2. 当遇到与URL匹配的组件后,停止渲染其他组件,避免多个路由同时被渲染。
  3. 如果没有与当前URL匹配的组件,可以通过<Switch><Route>组件作为默认路由。

下面是<Switch>组件的详细使用介绍:

  1. 渲染第一个匹配的路由:

    import { Switch, Route } from 'react-router-dom';function App() {return (<Switch><Route exact path="/" component={Home} /><Route path="/about" component={About} /></Switch>);
    }
    

    上述代码中,可以看到<Switch>包裹了两个<Route>组件,当URL为/时,只有<Route exact path="/" component={Home} />被渲染,而<Route path="/about" component={About} />将被忽略。

  2. 实现路由的优先级匹配:

    import { Switch, Route } from 'react-router-dom';function App() {return (<Switch><Route path="/users/:userId" component={User} /><Route path="/users/new" render={() => <NewUser />} /></Switch>);
    }
    

    上述代码中,当URL为/users/123时,只有<Route path="/users/:userId" component={User} />被渲染,而<Route path="/users/new" render={() => <NewUser />} />将被忽略。这是因为"/users/123"更精确地匹配"/users/:userId",所以优先渲染。

  3. 默认路由:

    import { Switch, Route } from 'react-router-dom';function App() {return (<Switch><Route path="/about" component={About} /><Route path="/" render={() => <DefaultPage />} /></Switch>);
    }
    

    上述代码中,当URL既不匹配"/about",也不匹配任何其他定义的路由时,只有<Route path="/" render={() => <DefaultPage />} />会被渲染,作为默认路由的内容。

通过上述的介绍,可以看出<Switch>的作用和使用方法。它通常用于包裹多个路由规则,以确保只有一个路由能够被渲染,提供更好的路由控制和优先级匹配的功能。

五、动态路由

在React Router中,动态路由匹配允许我们为一个路径创建一个带有动态参数的模板。这意味着我们可以通过设置一个通用的路径规则来匹配各种不同的URL,并将URL的一部分作为参数传递到我们的组件中。

使用动态路由匹配,我们可以轻松地创建可重用的路由组件,使我们的应用程序更灵活、模块化和可扩展。

下面是一个使用动态路由匹配的简单示例:

首先,我们需要引入React Router和所需的组件:

import React from 'react';
import { BrowserRouter, Route, Switch } from 'react-router-dom';
import Home from './Home';
import User from './User';

然后,我们可以在我们的路由配置中使用动态路由匹配:

const App = () => {return (<BrowserRouter><Switch><Route exact path="/" component={Home} /><Route path="/user/:id" component={User} /></Switch></BrowserRouter>);
}

在上面的例子中,我们定义了两个路由。第一个路由用于匹配根路径"/“,并将Home组件渲染为其对应的路由。第二个路由使用了动态路由匹配。它匹配以”/user/“开头的路径,并将剩余部分作为参数传递给User组件。例如,对于路径”/user/1",User组件将会被渲染,并且可以通过props中的match.params来获取id参数的值。

在User组件中,我们可以使用动态参数来执行特定的操作。例如,我们可以根据不同的id从数据源中获取相应的用户信息:

const User = ({ match }) => {const { id } = match.params;// 根据id从数据源中获取用户信息const user = getUser(id);return (<div><h2>User ID: {id}</h2><p>Name: {user.name}</p><p>Email: {user.email}</p></div>);
}

上述例子展示了如何使用React Router的动态路由匹配来根据不同的URL参数渲染相应的组件,并在组件中使用这些参数进行相关操作。通过这种方式,我们可以轻松地创建可复用的路由组件,并提高应用程序的灵活性和可扩展性。

六、useParams

React Router是一个用于构建单页面应用的库,它允许开发者根据URL的变化渲染不同的组件。useParams是React Router提供的一个自定义Hook,用于获取URL中的参数。

使用useParams可以方便地获取URL中的参数,这对于根据不同参数来展示不同内容的页面非常有用。通过使用useParams,我们可以轻松地获得路由中的动态路径参数,无需手动解析URL字符串。

下面是一个示例,演示了如何使用useParams来获取URL中的参数:

import React from 'react';
import { useParams } from 'react-router-dom';const ProductDetail = () => {const { id } = useParams();return (<div><h1>Product Detail</h1><p>Product ID: {id}</p></div>);
}export default ProductDetail;

在上述示例中,我们定义了一个ProductDetail组件。使用useParams从URL中获取到了一个参数id。在组件的渲染过程中,我们可以直接使用id变量来显示URL中的ID。

假设我们的路由配置如下:

<Route path="/products/:id" component={ProductDetail} />

当用户访问/products/123时,ProductDetail组件将被渲染,并且id参数将被设置为123。这样,我们就可以在页面上显示Product ID: 123了。

总结一下,useParams是React Router中的一个Hooks,用于获取URL中的参数。它使得我们可以方便地从URL中提取参数,并在组件中使用这些参数。这样,我们就可以根据不同的URL参数来显示不同的内容。

七、useRouteMatch

在React Router中,useRouteMatch是一个自定义Hook,它用于获取与当前URL匹配的路由信息。它返回一个包含以下属性的对象:

  1. path:定义在路由配置中的路径模式(字符串)。
  2. url:当前匹配的URL(字符串)。

path和url的区别在于,path是在路由配置中定义的路径模式,而url则是实际匹配的URL。

举例说明:

考虑以下路由配置:

<Switch><Route path="/users/:userId" component={UserDetails} /><Route path="/users" component={UsersList} />
</Switch>

在用户访问/users/123时,我们可以使用useRouteMatch来获取相关信息:

import { useRouteMatch } from "react-router-dom";function UserDetails() {const match = useRouteMatch();console.log(match.path); // "/users/:userId"console.log(match.url); // "/users/123"// ...
}function UsersList() {const match = useRouteMatch();console.log(match.path); // "/users"console.log(match.url); // "/users"// ...
}

在UserDetails组件中,path将是路由配置中定义的/users/:userId,而url将是实际匹配的URL/users/123。而在UsersList组件中,path和url将都是/users

举例说明
下面是一个示例来说明useRouteMatch的用法:

import React from "react";
import { BrowserRouter as Router, Route, Link, useRouteMatch } from "react-router-dom";const Users = () => {// 使用useRouteMatch获取匹配的路由对象const match = useRouteMatch();return (<div><h2>Users</h2><ul><li><Link to={`${match.url}/john`}>John</Link></li><li><Link to={`${match.url}/jane`}>Jane</Link></li></ul>{/* 渲染嵌套的路由 */}<Route path={`${match.path}/:user`} component={User} /></div>);
};const User = () => {// 使用useRouteMatch获取匹配的路由对象const match = useRouteMatch();const { user } = match.params;return <div>{`${user}'s profile`}</div>;
};const App = () => {return (<Router><div><nav><ul><li><Link to="/users">Users</Link></li></ul></nav><Route path="/users" component={Users} /></div></Router>);
};export default App;

在上面的示例中,我们创建了一个简单的用户管理系统。在Users组件中,我们通过调用useRouteMatch来获取匹配的路由对象,然后根据匹配对象的url属性来构建用户列表链接。同时,在User组件中也使用了useRouteMatch来获取匹配的路由对象,并根据匹配对象的params属性来获取当前用户的信息。

通过使用useRouteMatch钩子函数,我们可以方便地获取和处理与当前URL匹配的路由信息,从而实现更加灵活和强大的路由功能。

八、路由嵌套

在React项目中使用react-router库来管理路由,可以实现路由的嵌套。路由的嵌套是指在一个页面中嵌套另一个页面的路由,这样可以将页面划分为更小的组件,实现更好的代码组织和复用。

下面是一个使用react-router进行路由嵌套的示例:

import React from 'react';
import { BrowserRouter as Router, Route, Link } from 'react-router-dom';// 定义两个组件
const Home = () => <h2>Home组件</h2>;
const About = () => <h2>About组件</h2>;// 定义嵌套路由的组件
const App = () => {return (<Router><div><nav><ul><li><Link to="/">Home</Link></li><li><Link to="/about">About</Link></li></ul></nav><Route exact path="/" component={Home} /><Route path="/about" component={About} /></div></Router>);
};export default App;

在上面的示例中,我们使用了BrowserRouter组件作为根路由器,并定义了两个路由组件HomeAbout。在App组件中,使用Link组件来定义导航链接,其中to属性指定了链接地址。

nav中,我们定义了两个导航链接HomeAbout。当点击这些链接时,会渲染对应的组件。Route组件的path属性指定了路由的路径,component属性指定了对应的组件。

上面的示例中,/路径对应了Home组件,/about路径对应了About组件。这实现了基本路由的嵌套。

如果需要更深层次的嵌套,可以在HomeAbout组件中继续嵌套子路由。

例如,我们可以在Home组件中添加子路由:

import React from 'react';
import { BrowserRouter as Router, Route, Link } from 'react-router-dom';const Home = () => {return (<div><h2>Home组件</h2><nav><ul><li><Link to="/home/page1">Page 1</Link></li><li><Link to="/home/page2">Page 2</Link></li></ul></nav><Route path="/home/page1" component={Page1} /><Route path="/home/page2" component={Page2} /></div>);
};const Page1 = () => <h2>Page 1</h2>;
const Page2 = () => <h2>Page 2</h2>;const App = () => {return (<Router><div><nav><ul><li><Link to="/">Home</Link></li><li><Link to="/about">About</Link></li></ul></nav><Route exact path="/" component={Home} /><Route path="/about" component={About} /></div></Router>);
};export default App;

Home组件中,我们添加了两个子路由/home/page1/home/page2,并在nav中添加了对应的导航链接。子路由的路径是基于父路由的,所以完整的路径是/home/page1/home/page2

这样,当访问/home/page1/home/page2时,会渲染对应的子组件Page1Page2。可以看到,我们可以无限层级地嵌套路由来构建复杂的页面结构。

总结:
React-Router提供了RouteLink组件来实现路由的嵌套。通过在一个组件的render方法中定义子路由的路径和组件,可以实现对子组件的嵌套。可以通过导航链接Link来访问对应的路由,并渲染相应的组件。这样可以实现灵活的页面组织和路由控制。

九、路由重定向

在React中,可以使用react-router来实现路由的重定向。

要实现路由的重定向,可以使用<Redirect>组件或<Route>组件的render属性。下面分别介绍这两种方式的使用方法。

  1. 使用<Redirect>组件:
    首先,需要在路由配置中设置一个特殊的路径,用于重定向。然后,在需要进行重定向的地方,添加一个<Redirect>组件,将其to属性设置为目标路径。当用户访问特殊路径时,会自动进行重定向。

    例如,路由配置中设置了一个特殊路径/home,并且设置了<Redirect>组件,将其to属性设置为/about

    import { Redirect } from 'react-router-dom';function App() {return (<Router><Switch><Route exact path="/home"><Redirect to="/about" /></Route><Route path="/about"><About /></Route></Switch></Router>);
    }
    

    当用户访问/home时,会自动重定向到/about

  2. 使用<Route>组件的render属性:
    可以在<Route>组件的render属性中编写一个回调函数,来根据特定的条件进行重定向。

    例如,需要根据用户登录状态来判断是否进行重定向。在render属性中编写回调函数,根据登录状态进行判断,若未登录,则重定向到登录页面:

    import { Route, Redirect } from 'react-router-dom';function App() {const loggedIn = checkIfUserIsLoggedIn(); // 假设已实现一个函数来检查登录状态return (<Router><Switch><Route exact path="/home" render={() => (loggedIn ? (<Home />) : (<Redirect to="/login" />))} /><Route path="/login"><Login /></Route></Switch></Router>);
    }
    

    当用户访问/home时,会根据登录状态自动进行重定向。

这样,可以通过使用<Redirect>组件或<Route>组件的render属性来实现路由的重定向。根据实际需求,选择其中一种方式即可。

十、自定义link

在React Router中,可以通过封装Link组件来实现一些定制化的需求。封装Link组件可以帮助我们简化代码,提高代码复用性,并且可以根据具体业务需求进行一些特殊处理。

下面是一个简单的Link封装示例:

import React from "react";
import { Link } from "react-router-dom";const CustomLink = ({ to, activeOnlyWhenExact, className, activeClassName, children }) => {return (<Linkto={to}className={`${className} ${activeOnlyWhenExact ? activeClassName : ""}`}>{children}</Link>);
};export default CustomLink;

在这个示例中,通过定义一个名为CustomLink的组件,组件接收了以下几个props:

  • to:指定链接的目标URL。
  • activeOnlyWhenExact:一个布尔值,表示只有在当前URL与目标URL完全匹配时才激活链接。
  • className:指定链接的样式类。
  • activeClassName:指定链接在激活状态时的样式类。
  • children:链接中的内容。

在CustomLink组件中,通过使用Link组件来创建链接,并传递了适当的参数。className和activeClassName props被合并,以便在链接处于激活状态时添加activeClassName样式类。

使用CustomLink组件示例:

import React from "react";
import { BrowserRouter as Router, Route } from "react-router-dom";
import CustomLink from "./CustomLink";const App = () => {return (<Router><div><CustomLink to="/" activeOnlyWhenExact={true} activeClassName="active">Home</CustomLink><CustomLink to="/about" activeClassName="active">About</CustomLink><CustomLink to="/contact" activeClassName="active">Contact</CustomLink><Route exact path="/" component={Home} /><Route path="/about" component={About} /><Route path="/contact" component={Contact} /></div></Router>);
};const Home = () => <h2>Home</h2>;
const About = () => <h2>About</h2>;
const Contact = () => <h2>Contact</h2>;export default App;

在这个示例中,我们使用了CustomLink组件来代替原始的Link组件。CustomLink组件指定了目标URL和相应的样式类。根据具体的路由匹配情况,CustomLink组件会自动添加activeClassName样式类。

这是一个简单的封装示例,你可以根据具体需求扩展CustomLink组件,并为其添加额外的功能和样式。

十一、404路由

要实现匹配到所有未找到的路由,可以使用<Switch>组件和一个特殊的<Route>组件来匹配所有未找到的路径。

首先,我们需要在<Switch>组件内部添加所有其他的路由规则,确保它们在<Route>组件之前。然后,添加一个特殊的<Route>组件,没有指定path属性,它将匹配所有未找到的路径。可以在这个<Route>组件中处理未找到路径的逻辑。

以下是一个示例代码:

import React from 'react';
import { BrowserRouter as Router, Route, Switch } from 'react-router-dom';const App = () => {return (<Router><Switch><Route exact path="/" component={Home} /><Route path="/about" component={About} /><Route path="*" component={NotFound} /></Switch></Router>);
};const Home = () => {return <h1>Home page</h1>;
};const About = () => {return <h1>About page</h1>;
};const NotFound = () => {return <h1>Page not found</h1>;
};export default App;

在上面的示例中,<Switch>组件包含了<Route>组件的几个规则,分别是根路径//about,以及一个没有指定path属性的<Route>组件。当没有路径与之匹配时,它就会匹配到该规则,并渲染NotFound组件。

这样,当用户访问不存在的路径时,将会显示"Page not found"文本。

十二、route config

在这里插入图片描述
代码示例如下:

import React from "react";
import { BrowserRouter as Router, Switch, Route, Link } from "react-router-dom";// 有些人认为统一的路由配置很有价值。
// 路由配置只是数据。React非常擅长将数据映射到组件中,<Route>就是其中一个组件。// 我们的路由配置只是一组逻辑上的“路由”数组,包含了`path`和`component`属性,
// 以相同的方式进行排序,就像在`<Switch>`内部一样。
const routes = [{path: "/sandwiches",component: Sandwiches},{path: "/tacos",component: Tacos,routes: [{path: "/tacos/bus",component: Bus},{path: "/tacos/cart",component: Cart}]}
];export default function RouteConfigExample() {return (<Router><div><ul><li><Link to="/tacos">Tacos</Link></li><li><Link to="/sandwiches">Sandwiches</Link></li></ul><Switch>{routes.map((route, i) => (<RouteWithSubRoutes key={i} {...route} />))}</Switch></div></Router>);
}// 这是一个专门为<Route>的包装器,它知道如何通过将子路由传递给其渲染的组件的`routes`属性来处理“子”路由。
function RouteWithSubRoutes(route) {return (<Routepath={route.path}render={props => (// 通过传递子路由来保持嵌套<route.component {...props} routes={route.routes} />)}/>);
}function Sandwiches() {return <h2>Sandwiches</h2>;
}function Tacos({ routes }) {return (<div><h2>Tacos</h2><ul><li><Link to="/tacos/bus">Bus</Link></li><li><Link to="/tacos/cart">Cart</Link></li></ul><Switch>{routes.map((route, i) => (<RouteWithSubRoutes key={i} {...route} />))}</Switch></div>);
}function Bus() {return <h3>Bus</h3>;
}function Cart() {return <h3>Cart</h3>;
}

十三、useHistory

React Router中的useHistory是一个React Hook,它用于访问浏览器的历史记录栈,并且可以实现路由导航。

useHistory 提供了以下功能:

  1. 导航到不同的路由:通过调用push方法可以将用户导航到一个新的路由。例如:
import { useHistory } from 'react-router-dom';function MyComponent() {const history = useHistory();const handleClick = () => {history.push('/other-route');}return (<button onClick={handleClick}>Go to other route</button>);
}

在上面的示例中,当用户点击按钮时,页面将会导航到/other-route的路径。

  1. 替换当前路由:通过调用replace方法可以用一个新的路由替换当前的路由。它与push方法的区别在于,replace方法会在页面历史记录中替换当前路由,而不是在历史记录中添加一个新的条目。例如:
import { useHistory } from 'react-router-dom';function MyComponent() {const history = useHistory();const handleClick = () => {history.replace('/other-route');}return (<button onClick={handleClick}>Replace current route</button>);
}

在上面的示例中,当用户点击按钮时,页面将会用/other-route的路径替换当前的路由。

  1. 回退到前一个页面:通过调用goBack方法可以回退到前一个页面。例如:
import { useHistory } from 'react-router-dom';function MyComponent() {const history = useHistory();const handleGoBack = () => {history.goBack();}return (<button onClick={handleGoBack}>Go back</button>);
}

在上面的示例中,当用户点击按钮时,页面将会回退到前一个页面。

这些都是useHistory提供的一些常用功能,它可以帮助我们在React Router中进行路由导航操作。

十四、useLocation

在React Router中,useLocation是一个React Hook,它允许您从当前URL中获取当前位置信息。它可以用来访问URL的路径、查询参数以及状态对象。

useLocation常用属性如下:

  1. pathname: 表示当前URL的路径部分,例如,对于URL “https://example.com/products”,pathname将是 “/products”。
    举例:

    import { useLocation } from "react-router-dom";function MyComponent() {const location = useLocation();console.log(location.pathname); // 输出: "/products"return <div>...</div>;
    }
    
  2. search: 表示当前URL的查询参数部分,例如对于URL “https://example.com/products?sort=price”,search将是 “?sort=price”。
    举例:

    import { useLocation } from "react-router-dom";function MyComponent() {const location = useLocation();console.log(location.search); // 输出: "?sort=price"return <div>...</div>;
    }
    
  3. hash: 表示当前URL的哈希部分,例如对于URL “https://example.com/#section1”,hash将是 “#section1”。
    举例:

    import { useLocation } from "react-router-dom";function MyComponent() {const location = useLocation();console.log(location.hash); // 输出: "#section1"return <div>...</div>;
    }
    
  4. state: 表示与当前URL关联的状态对象。在路由之间传递数据时非常有用。

state属性是一个可以保存任意数据的JavaScript对象,用于在路由之间传递数据。它通常用于在路由跳转时传递一些特定的参数或状态。当从一个路由跳转到另一个路由时,可以将数据作为state传递给目标路由,然后在目标路由中使用useLocation().state来获取这些数据。

例如,假设有一个列表页面和一个详细页面,当用户点击列表中的某一项时,希望跳转到详细页面并传递该项的相关信息。可以在列表页面的路由设置中使用state属性来传递数据:

import { Link } from 'react-router-dom';function ListPage() {const itemList = [{ id: 1, name: 'Item 1' },{ id: 2, name: 'Item 2' },{ id: 3, name: 'Item 3' },];return (<div>{itemList.map(item => (<Linkkey={item.id}to={{pathname: `/detail/${item.id}`,state: { item } // 将item对象作为state传递给详细页面}}>{item.name}</Link>))}</div>);
}

在详细页面的组件中,可以使用useLocation().state来获取传递过来的数据:

import { useLocation } from 'react-router-dom';function DetailPage() {const location = useLocation();const item = location.state.item; // 获取传递过来的item对象return (<div><h3>{item.name}</h3><p>ID: {item.id}</p></div>);
}

上述例子中,点击列表页面中的某一项会跳转到详细页面,并传递该项的相关信息(即item对象)。在详细页面中可以获取到该项的信息并展示出来。

这些属性可以帮助您根据URL的不同部分来执行不同的操作,以及在应用程序中根据路由之间的状态传递数据。

十五、withRouter

withRouter 是一个高阶组件(Higher-Order Component),它可以将包裹的组件赋予路由的功能。React 中的路由可以使用 React Router 来管理,React Router 提供了一些组件来帮助我们在应用中实现路由功能,例如 Route、Link、Switch 等。

withRouter 的作用是将路由的相关属性(如 match、location、history)注入为被包裹组件的 props,这样被包裹组件就可以直接使用这些属性,而无需通过父组件传递或使用 context API。

举个例子,假设我们有一个 Person 组件,需要根据当前访问的 URL 来显示不同的人员信息。我们可以使用 withRouter 对 Person 组件进行包裹,这样它就可以获取到路由相关的属性。

import { withRouter } from 'react-router-dom';const Person = ({ match }) => {const { id } = match.params;// 根据 id 查询并显示对应的人员信息return (<div><h2>Person Details:</h2><p>ID: {id}</p>{/* 其他人员信息 */}</div>);
}export default withRouter(Person);

在上述例子中,我们使用 withRouter 包裹了 Person 组件,并通过解构赋值获取到了 match 对象。match 对象包含了一些路由相关的信息,如 params、url、path 等。通过 match.params.id 可以获取到当前访问 URL 中的 id 参数,然后根据该参数 进行查询或其他操作。

总之,withRouter 可以让被包裹组件拥有路由相关的属性,从而可以方便地对应用的路由进行操作。

十六、HashRouter,BrowserRouter

在React应用中,React Router是一个用于管理页面路由的库。它允许开发者在应用中创建多个页面,通过URL进行导航。React Router提供了两个主要的路由器组件:<BrowserRouter><HashRouter>

1. <BrowserRouter>
- <BrowserRouter>使用HTML5的history API来管理页面的URL,这意味着它可以在不刷新整个页面的情况下,实现URL的更新和页面的导航。

  • 它通过从URL获取信息来渲染相应的组件。
  • 在使用<BrowserRouter>时,需要进行一些服务器的配置来确保在浏览器进行页面刷新时能正确地加载应用的入口点。

举例说明:

import React from 'react';
import { BrowserRouter, Route, Link } from 'react-router-dom';const Home = () => <h1>Home Page</h1>;
const About = () => <h1>About Page</h1>;const App = () => {return (<BrowserRouter><div><ul><li><Link to="/">Home</Link></li><li><Link to="/about">About</Link></li></ul><Route path="/" exact component={Home} /><Route path="/about" component={About} /></div></BrowserRouter>);
}export default App;

上述例子中,使用<BrowserRouter>来包裹整个应用。通过<Route>组件来指定URL和相应的组件,<Link>组件用于导航到不同的URL。

2. <HashRouter>

  • <HashRouter>使用URL中的哈希部分(#)来管理页面的URL。
  • 它不需要使用服务器配置,可以直接在静态文件服务器上运行。
  • 在使用<HashRouter>时,所有的URL都会包含一个哈希值,例如:http://example.com/#/about

举例说明:

import React from 'react';
import { HashRouter, Route, Link } from 'react-router-dom';const Home = () => <h1>Home Page</h1>;
const About = () => <h1>About Page</h1>;const App = () => {return (<HashRouter><div><ul><li><Link to="/">Home</Link></li><li><Link to="/about">About</Link></li></ul><Route path="/" exact component={Home} /><Route path="/about" component={About} /></div></HashRouter>);
}export default App;

在上述例子中,使用<HashRouter>来包裹整个应用。URL中的哈希部分(例如:#/about)将被<HashRouter>解析,并根据<Route>组件的配置来渲染相应的组件。

总结:React Router提供了两种路由器组件,<BrowserRouter><HashRouter>,用于管理页面的URL和导航。<BrowserRouter>使用HTML5的history API来管理URL,<HashRouter>使用URL中的哈希部分。选择使用哪个取决于应用的部署环境和需求。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/128730.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

shardingphere Sharding count cannot be null解决方案

shardingphere Sharding count cannot be null解决方案 问题背景解决方案Lyric&#xff1a; 我知道坚持要走 问题背景 使用shardingphere分表分库时&#xff0c;出现分表算法设置错误 Caused by: java.lang.IllegalArgumentException: Sharding count cannot be null.at com.…

mapbox使用marker创建html点位信息

mapbox使用marker创建html点位信息 codePen地址 mapboxgl.accessToken "pk.eyJ1IjoibGl1emhhbzI1ODAiLCJhIjoiY2xmcnV5c2NtMDd4eDNvbmxsbHEwYTMwbCJ9.T0QCxGEJsLWC9ncE1B1rRw"; const center [121.29786, 31.19365]; const map new mapboxgl.Map({container: &quo…

双十一买电视盒子什么牌子好?拆机达人强推目前性能最好的电视盒子

我这几年拆过的电视盒子已经有40多款了&#xff0c;最近看到网友们在讨论双十一电视盒子怎么挑选&#xff0c;就我拆机的经验来说&#xff0c;有些产品在硬件上存在问题的确较多&#xff0c;不知道双十一买电视盒子什么牌子好&#xff0c;可以参考我整理的目前性能最好的电视盒…

windows 运行 Mysql Command Line Client 自动关闭闪退原因分析

目录 原因分析一 原因分析二 原因分析三 第一次使用 MySQL Command Line Client 有可能输入密码后一按下回车键&#xff0c;程序窗口就自动关闭&#xff0c;出现闪退现象。本节主要分析产生闪退现象的原因以及如何处理这种情况。 原因分析一 首先可以查看程序默认执行文件…

电源管理(PMIC)MAX20428ATIA/VY、MAX20428ATIC/VY、MAX20428ATIE/VY适合汽车ADAS应用的开关稳压器

一、概述 MAX20428是一款高效率、八路输出、低压PMIC。OUT1将输入电源升压至5V&#xff0c;电流高达500mA&#xff0c;而三个同步降压转换器的输入电压范围为3.0V至4.2V&#xff0c;输出电压范围为0.8V至3.9875V&#xff0c;峰值电流分别高达1.3A、1.3A和3.5A。三个300mA pMOS…

团队表 -多级团队设计

团队表 -多级团队设计 user_team团队表 &#xff0c;如果存在子团队 1.我们可以通过每一个团队字段加一个parentid &#xff08;相当于一对多的关系&#xff09; 2.还可以设置一个字段CodingNum,比如这样: //系统为了管理查询团队自动生成的有序编号 可以使用3位数代表一个…

Spring cloud教程Gateway服务网关

Spring cloud教程|Gateway服务网关 写在前面的话&#xff1a; 本笔记在参考网上视频以及博客的基础上&#xff0c;只做个人学习笔记&#xff0c;如有侵权&#xff0c;请联系删除&#xff0c;谢谢&#xff01; Spring Cloud Gateway 是 Spring Cloud 的一个全新项目&#xff0c;…

JS中null和undefined的区别

首先 Undefined 和 Null 都是基本数据类型&#xff0c;这两个基本数据类型分别都只有一个值&#xff0c;就是 undefined 和 null。 undefined 代表的含义是未定义&#xff0c;null 代表的含义是空对象。一般变量声明了但还没有定义的时候会返回 undefined&#xff0c;null主要…

使用HttpClient库的爬虫程序

使用HttpClient库的爬虫程序&#xff0c;该爬虫使用C#来抓取内容。 using System; using System.Net.Http; using System.Threading.Tasks; ​ namespace CrawlerProgram {class Program{static void Main(string[] args){// 创建HttpClient对象using (HttpClient client new…

Ubuntu更新apt-get安装镜像源

前往清华开源镜像站获取镜像链接 修改镜像源&#xff0c;打开配置文件&#xff0c;将镜像源链接粘贴到配置文件 sudo vim /etc/apt/sources.list更新软件列表到本地 sudo apt-get update更新所有软件&#xff08;非必要&#xff09; sudp apt-get upgrade

java入门,程序=数据结构+算法

一、前言 在学习java的时候&#xff0c;我印象最深的一句话是&#xff1a;程序数据结构算法&#xff0c;对于写java程序来说&#xff0c;这就是java的入门。 二、java基本数据结构与算法 1、数据类型 java中的数据类型8种基本数据类型&#xff1a; 整型 byte 、short 、int…

win7中安装node14和vue

下载并安装低版本node 13 到官网去找早期历史版本的 nodejs 13 msi格式即可&#xff0c;并一键安装&#xff0c;我安装在了 D:\Program Files\nodejs 目录下 https://nodejs.org/download/release/v13.14.0/ 下载高版本node 14 下载高版本的node zip包 https://nodejs.org/…

VMware打开centos黑屏解决方法汇总以及解决出现的bug(Centos7系统网络异常等)

VMware打开centos黑屏解决方法汇总 前言&#xff1a;一. VMware打开centos黑屏解决方法汇总一 .情况情况一&#xff1a;情况二情况三 二. 解决方法最简单的方法&#xff1a;一. 以管理员权限在命令行执行1. 管理员身份运行cmd2. 输入“netsh winsock reset”,回车3. 重启电脑即…

影视企业有哪些方式将视频文件快速海外跨国传输国内?

影视行业是一个高度国际化的行业&#xff0c;影视企业在跨国合作、制作、发行等方面有着强烈的需求。然而&#xff0c;影视企业在跨国文件传输方面也面临着诸多的问题和难题。视频文件通常具有较大的文件大小、多样的文件格式、高要求的文件质量等特点&#xff0c;这些特点使得…

激光雷达标定板如何提高激光雷达避免误判的精准度

激光雷达在提高自动驾驶的安全性方面具有重要作用。它通过高精度测量、避免误判、实时感知、适应不同环境和结合其他传感器等方式&#xff0c;为自动驾驶系统提供准确、可靠的感知数据&#xff0c;从而确保行驶的安全性和稳定性。 激光雷达可以通过以下方式避免误判&#xff1a…

web3 在React dapp中全局管理web3当前登录用户/智能合约等信息

上文 Web3 React项目Dapp获取智能合约对象我们在自己的前端dapp项目中链接获取到了 自己的智能合约 我们继续 我们还是先启动ganache环境 终端输入 ganache -d然后发布一下我们的智能合约 打开我们的合约项目 终端输入 truffle migrate --reset这样 我们的智能合约就部署到区…

MVCC详解

什么是MVCC&#xff1f; MVCC&#xff0c;即Multi-Version Concurrency Control &#xff08;多版本并发控制&#xff09;。它是一种并发控制的方法&#xff0c;一般在数据库管理系统中&#xff0c;实现对数据库的并发访问&#xff0c;在编程语言中实现事务内存。 通俗的讲&am…

无显示器和网线安装树莓派4B Raspbian 操作系统

1、下载Raspbian镜像&#xff1a; 下载地址&#xff1a;Operating system images – Raspberry Pi 推荐预装软件带桌面的系统&#xff0c;点击download按钮&#xff0c;大概2.5G&#xff0c;漫长下载ing。下载完毕之后&#xff0c;解压得到一个后缀是img的镜像文件备用。 2、…

银河麒麟x86版、银河麒麟arm版操作系统编译zlmediakit

脚本 # 安装依赖 gcc-c.x86_64 这个不加的话会有问题 sudo yum -y install gcc gcc-c libssl-dev libsdl-dev libavcodec-dev libavutil-dev ffmpeg git openssl-devel gcc-c.x86_64mkdir -p /home/zenglg cd /home/zenglg git clone --depth 1 https://gitee.com/xia-chu…

OpenCV的绘图工具(rectangle、circle、line、polylines、putText)常用方法简介【C++的OpenCV 第十五课】

&#x1f389;&#x1f389;&#x1f389; 欢迎各位来到小白 p i a o 的学习空间&#xff01; \color{red}{欢迎各位来到小白piao的学习空间&#xff01;} 欢迎各位来到小白piao的学习空间&#xff01;&#x1f389;&#x1f389;&#x1f389; &#x1f496; C\Python所有的入…