react目前用的路由是版本是4 ;分为 react-router-dom(浏览器) 和 react-router-native(原生app);
目前版本2和版本4完全是两个东西 ,需要重新开始学习。
第一部分:
核心概念 : 动态路由,Route ,link ,switch.
1,BrowserRouter 最外层包裹整个应用;(分为HashRouter和BrowserRouter,这里我们选择了url更友好的BrowserRouter);
2,route是路由对应的渲染组件 可以嵌套;多个route 需要用div来包裹起来 ;
3,link 是跳转用的标签;
如果route的path 是‘/’,那么 会出现 包含“/”的 路径都会 渲染“/”组件;这是由于 路径是正则匹配的; 解决这个问题 ,只需要在“/”路径匹配的组件内加入 exact属性就好了(完全匹配“/”);
第二部分:
1,URL 传参 ,router组件内 可以把参数挂通过冒号: 挂在path后面; 比如 path="/:id",
2,Redirect 跳转组件(我们有两种跳转方式 1.组件跳转2,hashistory的push(路径)方法跳转,这个是router2的方法)
使用这个 组件会导致浏览器throw出warning :
index.js:2178 Warning: You tried to redirect to the same route you're currently on: "/erying";
作用就是 进入页面 直接进入到Redirect to的那个位置 ;就是一个强制跳转
3,Switch组件 只渲染一个子route组件;(只渲染第一个命中的子组件)
如果我们打印当前的子组件的props ,那么我们会看到下面挂着三个属性: history;location;match;
history 是历史路径 可以用this.props.history(路径名),这种方式去传参,这个是router2的方法;
location 是关于页面信息的;
match是要匹配的一些信息;
其中传参的id 就挂在match属性下面的params下, 因此我们拿到 id的 方法为 this.props.match.params.X; 就拿到了该属性;
第三部分:
这部分 利用redux和react-router 4来构建复杂应用了
其实也没啥好说的 只要你觉得爽 干就对了;
只需记住 react里route 各个页面都可以随便引入 随便扔就可以 我觉得他是全局注册了;
废话不多说 直接上代码 dashboard..redux.js
const LOGIN="login"; const LOGOUT="logout"; export function auth(state={isauth:false,user:"李云龙"},action) { switch (action.type){ case LOGIN: return {...state,isauth:true} case LOGOUT: return {...state,isauth:false} default: return state } } export function login() { return {type:LOGIN} } export function logout() { return {type:LOGOUT} }怎么样是不是很亲切 ;redux还是需要勤学苦练啊,end
第四部分:
这个时候就会有两个reducer; 但是他们只有一个 state ,这个时候就会需要 用到redux的合并reducer 来处理这种复杂的情况
API是 combineReducers
import {combineReducers} from "redux"; import {counter} from "./reducer/reducer"; import {auth} from "./DashBoard.redux" export default combineReducers({counter,auth})
然后到store 里 引入这个 reducer 的集合就可以了
store.getState()调用打印发现
这个state里,各个reducer被分配成了state的属性,比如上面的就变成{counter:10,auto:{isauth:false,user:"李云龙"}}
现在 在connect 里的第一个参数就是 (state)=>{return {num :state.counter}} ;需要啥属性把 reducer的名字挂上去就可以拿到了;
然后就是一些技巧性的东西 没必要多说啥;
说个坑吧:
这边在定义变量的时候 别用关键字 : 除了class for这些老生常谈, 这边 扩展了 一些 路由的关键名字也不能用
例如Switch Redirect 否则 呵呵 分分钟死给你看 ,就是这么傲娇;
报这个错:
React.createElement: type is invalid -- expected a string (for built-in components) or a class/function (for composite components) but got: undefined. You likely forgot to export your component from the file it's defined in, or you might have mixed up def
obj在定义key名的时候也有一些禁忌 比如我上次key为add也是死的很难看 ;
debugger都无解;
还有注意引入reducer不要引入错了 这边都不抛异常出来的 要细心;
还有一个坑 就是@connect(1,2) 第一个参数必须是return 回来一个对象 不是对象就造一个对象进去;
另外 个人有个习惯 把action生成器引入的时候 喜欢 * as X 这样引入 还是算了吧,老老实实的需要几个引入 几个 ,减少去不到值,赋值混乱的情况;
在最后 其实路径都可以通过 this.props.match取到;
下面挂了几条属性:
path 这个可以用来传参数
url: 这个就是实际的地址了
const match=this.props.match.url;
<li><Link to={`${match}`}>yiying</Link></li>
<Route path={`${match}`} exact component={App} />
通过 match 下面的url属性和 字符串模版语法就可以去 达到 我们想要的效果了
大写的END
一点补充:
如果说 组件没有被Route包裹;那么这个时候组件哪不是接收不到this.props.history 的;因为他没有在路由里注册
也就拿不到地址栏上的path ;
这个时候就需要用到一个东西了----withRouter
import {withRouter} from "react-router-dom"; @withRouter这样就可以在没有被route包裹的组件,就可以在内部获得 this.props.history的相关信息,从而拿到地址的信息;