浅谈react-router@4.0使用方法和源码分析
简介
React-Router是在React上的一个强大路由器。它可以处理导航并使页面发生渐进式加载。React-Router@4相对于上一版本有了许多改进,如无需添加任何特定的MIXIN,以及更好的文档。
使用方法
在使用React-Router之前,你必须先安装它。你可以直接在终端中输入命令来进行安装:
npm install --save react-router-dom
安装完毕后,我们就可以在React应用程序中使用React-Router了。首先,我们需要在应用程序的入口文件中引入React-Router:
import { BrowserRouter as Router, Route, Link } from 'react-router-dom';
这行代码引入了三个模块:
- Router:这是React-Router最重要的组件之一。这个组件是React应用程序的核心,并管理路由的状态。
- Route:这个组件用于匹配给定的路径,并渲染相应的组件。
- Link:这个组件是HTML中的超链接。但React-Router会将这个组件转化为应用程序中的导航链接。
使用React-Router的核心就是Router组件和Route组件。Route组件用来声明给定的路径将会渲染的组件,而Router组件告诉React哪些路径将使用哪个Route组件。
接下来我们在应用程序中加入BrowserRouter:
ReactDOM.render((
<Router>
<App />
</Router>
), document.getElementById('root'))
现在你已经准备好创建你的第一个React-Router应用程序了。让我们来看一个简单的示例:
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 Topic = ({ match }) => (
<div>
<h3>{match.params.topicId}</h3>
</div>
)
const Topics = ({ match }) => (
<div>
<h2>Topics</h2>
<ul>
<li>
<Link to={`${match.url}/rendering`}>
Rendering with React
</Link>
</li>
<li>
<Link to={`${match.url}/components`}>
Components
</Link>
</li>
<li>
<Link to={`${match.url}/props-v-state`}>
Props v. State
</Link>
</li>
</ul>
<Route path={`${match.path}/:topicId`} component={Topic}/>
<Route exact path={match.path} render={() => (
<h3>Please select a topic.</h3>
)}/>
</div>
)
const BasicExample = () => (
<Router>
<div>
<ul>
<li><Link to="/">Home</Link></li>
<li><Link to="/about">About</Link></li>
<li><Link to="/topics">Topics</Link></li>
</ul>
<hr/>
<Route exact path="/" component={Home}/>
<Route path="/about" component={About}/>
<Route path="/topics" component={Topics}/>
</div>
</Router>
)
export default BasicExample;
大多数React-Router的核心概念和API都出现在这个示例中。请注意,我们使用了Link组件来创建导航链接,使用Route组件来声明路径对应的组件。在组件中,这些参数都可以通过props来访问。
为了让这个示例运行起来,你需要将其保存为一个.jsx文件,并使用webpack进行打包。
源码分析
对路径的匹配
React-Router@4将路径匹配分为了三个部分:路径中的参数、路径的规则、路径分组。
您可以使用params来从URL中获取动态参数,例如:/users/:userId
规则使您可以声明路径的模式应该匹配哪些部分。例如,使用大括号包围的参数是参数:
/users/:userId/
他将匹配这些路径:
/users/5/
/users/0B/
/users/abcdefg/
分组是一种定义一组子路由的方法,它们由一个父路由显式地声明。例如:
<Router>
<Route path="/" component={App}>
<Route path="about" component={About} />
<Route path="company" component={Company} />
<Route path="privacy" component={Privacy} />
</Route>
</Router>
这个示例将使用App组件,但是子路由中的内容将根据URL渲染。
Router组件
Router是React-Router中最重要的组件之一。它使用了许多React的高级概念如上下文。Router的作用是处理URL并在需要时显示正确的组件。
Route组件
Route是React-Router中的另一个重要组件。它告诉Router如何显示应用程序的不同部分。
Route有两个必需属性:path和component。path告诉Route匹配哪些路由,component告诉Route需要渲染的React组件。当某个路由与Route的path匹配时,Route会将URL中的任何参数提取并传递给渲染的组件作为props。
例如:
<Route path="/users/:userId" component={UserProfile} />
UserProfile组件可以通过props来访问适用于userID的属性。
Link组件
Link是React-Router中的一个重要组件,它用于处理用户在UI中的导航。它通过URL而不是基于JavaScript而进行导航。
<Link to="/about">About</Link>
示例一:基于路径传递参数
import React from "react";
import {
BrowserRouter as Router,
Route,
Link,
Switch
} from "react-router-dom";
const Home = () => <div>home</div>;
const About = () => <div>about</div>;
const Topic = ({ match }) => (
<div>
<h3>{match.params.topicId}</h3>
</div>
);
const Topics = ({ match }) => (
<div>
<ul>
<li>
<Link to={`${match.url}/some-topic-1`}>some topic 1</Link>
</li>
<li>
<Link to={`${match.url}/some-topic-2`}>some topic 2</Link>
</li>
</ul>
<Route path={`${match.path}/:topicId`} component={Topic} />
</div>
);
class App extends React.Component {
render() {
return (
<Router>
<div>
<ul>
<li>
<Link to="/">home</Link>
</li>
<li>
<Link to="/about">about</Link>
</li>
<li>
<Link to="/topics">topics</Link>
</li>
</ul>
<Switch>
<Route exact path="/" component={Home} />
<Route path="/about" component={About} />
<Route path="/topics" component={Topics} />
</Switch>
</div>
</Router>
);
}
}
export default App;
这个示例演示了如何在Route的path属性中包含参数。例如,在Topics组件中,我们有两个Route:一个匹配“/topics”路径,一个带参数的Route匹配路径为“/topics/:topicId”。我们还使用Link组件来引用这些URL,并在Topic组件中渲染了一个动态ID。
示例二:基于布尔值进行导航
import React from "react";
import { BrowserRouter as Router, Route, Link } from "react-router-dom";
const Home = () => <div>home</div>;
const LoginPage = () => (
<div>
<h2>Login Page</h2>
</div>
);
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
isLoggedIn: false
};
}
render() {
return (
<Router>
<div>
<ul>
<li>
<Link to="/">home</Link>
</li>
<li>
<Link to="/login">login</Link>
</li>
</ul>
<Route exact path="/" component={Home} />
{this.state.isLoggedIn ? (
<div>show some protected routes</div>
) : (
<Route path="/login" component={LoginPage} />
)}
</div>
</Router>
);
}
}
export default App;
在这个示例中,我们使用了state来维护用户是否登录。如果用户已经登录,我们可以为他展示受保护的路由。否则,我们将重定向到一个login页面,它根据用户的登录状态进行渲染。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:浅谈react-router@4.0 使用方法和源码分析 - Python技术站