一、路由基础组件
1、路由优势:
只需要一次请求。
2、路由实现原理:
a标签改变url,但阻止默认跳转的请求,通过e.preventDefault()来阻止,然后再通过history.push()改变浏览器的url。最后通过url来匹配不同的组件渲染。
Link组件实现原理
const Link=({to,children}) =>(
<a href={to} onClick={(e) =>{
e.preventDefault();
history.push(to);
}}>
{children}
</a>
)
Route组件实现原理
将url匹配路径渲染不同的组件。
const Route=({path,component}) =>{
const pathname=window.location.pathname;
if(pathname.match(path)){
return (
React.createElement(component)
)
}else{
return null;
}
}
Redirect 组件实现原理
Redirect组件和link组件类似,只是不需要点击,直接跳转,什么也不渲染,只是改变浏览器的url路径。
class Redirect extends React.Component {
static contextTypes={
history:PropTypes.object
}
componentDidMount(){
const history=this.context.history;
const to=this.props.to;
history.push(to)
}
render(){
return null
}
}
3、路由使用
- Route
1)path和component
指定和URL匹配的路径和需要渲染的组件
<Route path='/atlantic' component={Atlantic} />
除了path和component两个属性还可以呦其他特性
2)render
<Route path='/' render={() => (
<h3>
Welcome! Select a body of saline water above.
</h3>
)} />
问题:由于Route组件中判断和url的pathname是否匹配用的是match,
if(pathname.match(path))
所以当url是’http://localhost:3000/atlantic/ocean‘时,path=’/atlantic‘和path=’/atlantic/ocean‘都能匹配。所以这两个组件都回渲染。
当我们需要精确匹配时,需要加上exact这个属性
<Route exact path='/' render={() => (
<h3>
Welcome! Select a body of saline water above.
</h3>
)} />
4、Switch
将Route写在Switch里时,路径只会匹配一次,即使都能匹配后边的也不能渲染成功。在Switch组件最后边可以防止一个默认匹配,即前边没有任何匹配到的路由就进行最后一个路由的默认渲染,也就是说最后一个路由能匹配到所有路径。
<Switch>
<Route path='/atlantic/ocean' render={() =>(
<div>
<h3>Atlantic Ocean — Again!</h3>
<p>
Also known as "The Pond."
</p>
</div>
)}/>
<Route path='/atlantic' component={Atlantic}/>
<Route path='/pacific' component={Pacific}/>
<Route path='/black-sea' component={BlackSea}/>
<Route exact path='/' render={() => (
<h3>
Welcome! Select a body of saline water above.
</h3>
)} />
<Route render={({location}) =>(
<div className='ui inverted red segment'>
<h3>
Error! No matches for <code>{location.pathname}</code>
</h3>
</div>
)}/>
</Switch>