Open liyatang opened 7 years ago
添加一些没记录到的地方
// V2 or V3
import { Router, Route, hashHistory } from 'react-router';
<Router history={hashHistory}>
<Route path='/foo' component={Foo} />
<Route path='/bar' component={Bar} />
</Router>
// V4 Router组件里只能渲染一个组件
import {
HashRouter as Router,
Route
} from 'react-router-dom';
<Router>
<div>
<Route path='/foo' component={Foo} />
<Route path='/bar' component={Bar} />
</div>
</Router>
// V2 or V3 路由组件嵌套
import { Router, Route, hashHistory } from 'react-router';
<Router history={hashHistory}>
<Route path='/' component={App}>
<Route path='foo' component={Foo} />
<Route path='bar' component={Bar} />
</Route>
</Router>
// V4 Router 的路由组件嵌套
import {
HashRouter as Router,
Route,
Switch
} from 'react-router-dom';
<Router>
<Route path="/" component={(props) => (
<App {...props}>
<Switch>
<Route path='/foo' component={Foo} />
<Route path='/bar' component={Bar} />
</Switch>
</App>
)}/>
</Router>
在react-router V4
中去掉了on****
的路由生命周期的钩子,但是你可以在组件中用componentDidMount
或 componentWillMount
代替 onEnter
,可以用componentWillUpdate
或 componentWillReceiveProps
代替 onUpdate
,你可以用componentWillUnmount
代替 onLeave
。
push之后地址栏url改变但是页面没有刷新,请问你有没有遇到过 import createHashHistory from 'history/createBrowserHistory' const history = createHashHistory()
history.push({ pathname: '/login' })
@svkd9 情况太多,建议提供简易版demo。 几个思路可以看下: 1 路由设置对了? 2 跳转过去的路由有错?
感谢回复,下面是我写的了一个简单的demo https://github.com/svkd9/react-router_v4_demo.git
@svkd9 sorry,同蒙圈。 不过我换成 createHashHistory 就没问题了。 至于 createBrowserHistory 为啥不行目前还没答案。
我来解答一下为何 createHashHistory可以, 但是createBrowserHistory 不行吧! 首先,上面的HashRouter 和BrowserRoute里面都是内含有 history对象的,这一点 @liyatang 也说了。
其实这个问题解释不难,照着逻辑去定位一下就可以了
(ps: router本身是用history事件订阅去触发router组件更新的, 所有关键是寻找如何触发history订阅的事件)
因为window对象有个 hashchange 事件 可以监听哈希的变化
在hashHistory中, 通过window去监听hashchange变化 而去触发history订阅的事件的(即router组件更新)源码 即无论哪个history对象触发的hash变化,都会被window监听到,而且执行路由更新,所以hashRouter是没问题的。
但是浏览器并没有直接监听url变化的事件, 所以broserHistory变化本身只能使用同一个history对象的执行本身的的事件订阅模式去触发组件的更新,当然代码里面还增加了 对window对象的的 hashchange 和 popstate 事件监听
@liyatang @svkd9
豁然开朗,谢谢。 @yongningfu
大概浏览了一下你们组件库的代码,确实逻辑处理的还是非常清晰的,能直接封装一套适合公司用的ui, 感觉还是很棒的,你们还招人么? @liyatang
@yongningfu 加微信 wxliyatang
@fondadam @liyatang 关于用componentDidMount 或 componentWillMount 代替 onEnter的问题, 如果路由的位置用到onEnter(nextState, replace, callback);因为该方法中的异步如果没有返回,页面就不会渲染。所以有时会将用户的验证放在该方法中的,可是如果改成放到componentWillMount,如果有异步验证并且还没返回的时候,是不是页面就不渲染组建(组件中的请求需要用户验证之后)同时页面还需要特意声明一个state状态
是否我需要js跳转路由的组件,都需要 import createHistory from 'history/createHashHistory' const history = createHistory() 这样不麻烦. 不能用this.出来么
@AlanZou007 你可以把history保存起来
请问,router@4中,“只有当访问地址和路由匹配时,一个 React component 才会被渲染”。我现在是结合了antd,实现tab标签。而tab标签的切换是不会导致地址栏发生变化的,因此不会渲染组件。有没有解决办法呢?
@JesterCheung 理下你需求是否这样: tab切换会带动地址栏变化?
那你在切换的时候 history.push(xxxx) 就ok了,把tab的状态当成路由的参数。
eg 路由设置成 xxxxxx/#/A/B?tab=1
切换tab的时候
history.push({
pathname: 'xxxxxx/',
search: '?tab=1'
})
btw,tab一般不建议做成导致地址栏变化。 至于切换tab,组件是否渲染是tab的实现方式问题,属于另外个话题。 可以把代码抛出来讨论。
import React, { Component } from 'react';
import { Router, Route, Link, Switch, HashHistory } from 'react-router-dom';
import PropTypes from 'prop-types';
import './app.css'
import Goods from './pages/goods/goods'
import Active from './pages/active/active'
import Detail from './pages/detail/detail'
import Home from './pages/home/home'
import createHistory from 'history/createHashHistory'
const history = createHistory()
class App extends Component {
constructor () {
super()
this.state = {
}
}
render() {
return (
<Router history={history}>
<div className="container">
<div className="siderBar">
<ul>
<li className="siderBar_btn"><Link to="/">首页</Link></li>
<li className="siderBar_btn"><Link to="/goods">商品专区</Link></li>
<li className="siderBar_btn"><Link to="/detail">商品详情</Link></li>
<li className="siderBar_btn"><Link to="/active">活动</Link></li>
</ul>
</div>
<div className="content">
<h1 className="title">解码器1.0</h1>
<Route render={({ location }) => {
return (
<Switch>
<Route path="/" component={Home} />
<Route path="/goods" component={Goods} />
<Route location={location} path="detail" component={Detail} />
<Route location={location} path="active" component={Active} />
</Switch>
)
}} />
<div className="footer"><img src={require('./assets/logo.png')} /></div>
</div>
</div>
</Router>
)
}
}
export default App;
请问我的问题出在哪?url变化,路由不跳转,重复点击的话提示Warning: Hash history cannot PUSH the same path; a new entry will not be added to the history stack warning @ browser.js?e722:49 折腾了我好久,求告知谢谢~
以下mark MA切换react-router4过程中注意点
文档
https://github.com/react-translate-team/react-router-CN https://reacttraining.cn/
库
使用了两个库 react-router 通用库,web 和 Native 都可用 react-router-dom web用
Router Route
不累赘,看文档和MA代码吧,✌️
Link
history
service.js 中history的提供方式变了
query search
query 切到了 search,且search是字符串类型 query => search(obj =>string)
具体文档见 https://github.com/ReactTraining/history
push && replace
history.replace 同理,不累赘
props
route提供的props也变更。react-router2 提供 location, history, params,react-router4 提供 location, history, match
其中 location.query (obj) => location.search(string) 需要自己对字符串处理,可引入 query-string
props.params -> props.match.params
兼容
由于 query 和 params 以前业务用的多,一下子切过去有风险,估做了兼容逻辑,保证react-router2的这部分能用,但未来还是会废弃掉的
怎么做的 ?
会对react-router提供的props做加工处理,提供query 和 params,代码见gm-util
对history的方法做处理