欢迎访问 生活随笔!

生活随笔

当前位置: 首页 >

Router+Redux学习总结

发布时间:2024/1/8 83 豆豆
生活随笔 收集整理的这篇文章主要介绍了 Router+Redux学习总结 小编觉得挺不错的,现在分享给大家,帮大家做个参考.

一、React-Router配置路由

在实际应用中,我们不可能只有一页页面,切换页面需要通过Router配置,这样输入不同的url就能看到不同的页,或者点击不同的按钮可以在下方加载不同的组件。
说明:这里补充一下组件的概念,其实其本质就是一个类。在页面中我们可以把页面分为导航区,侧边栏,工作区等不同区域,每个区域都是一个组件,组件中还可以继续细分为其他组件。想象在创建页面的时候把不同的组件拿来组合在一起,页头页尾这种公用组件可以始终保持不动,只切换我们想切换的区域。

一般来讲,我们用React-router-dom来实现,它提供了BrowserRouter, Route, Link等api,让我们可以通过dom事件控制路由。
第一步还是安装。

npm install react-router-dom --save

这时我们新建两个组件AAA.js和BBB.js。

import React, { Component } from 'react';class AAA extends Component {render() {return (<div><h1>AAA</h1></div>)} } export default AAA; import React, { Component } from 'react';class BBB extends Component {render() {return (<div><h1>BBB</h1></div>)} } export default BBB;

并且在首页上搞两个按钮。(不会搞的请去看上一篇 https://blog.csdn.net/qq_40241957/article/details/100726297)

然后,将刚刚的两个组件,和React-router-dom中的一些api导入首页app.js。这里我们用了BrowserRouter,当然也可以用HashRouter,差别就是地址栏有没有#。嗯比如用HashRouter地址栏就是http://localhost:3000/#/。(好像还有别的差别但是我不知道Σ(⊙▽⊙")

import { BrowserRouter, Route, Link, Switch } from 'react-router-dom'; import AAA from './aaa'; import BBB from './bbb';

然后在Dom里用Link来改变地址栏的url,注意Link,Route这些api都需要写在<BrowserRouter>里

<BrowserRouter> <div className="App"><Button type="primary"><Link to='/aaa'>假装自己是个导航</Link></Button><Button><Link to='/bbb'>假装自己是另一个</Link></Button></div></BrowserRouter>

此时点击按钮可以看到地址栏是改变的,会变成http://localhost:3000/aaa和http://localhost:3000/bbb。
然后,在下方加上要通过路由切换的组件,当path为aaa或者bbb的时候分别加载AAA和BBB。

<BrowserRouter> <div className="App"><Button type="primary"><Link to='/aaa'>假装自己是个导航</Link></Button><Button><Link to='/bbb'>假装自己是另一个</Link></Button><Switch> //下面的exact是精准匹配的意思,比如当path=“/”时,就只能匹配/,不能匹配其他的比如/aaa,/bbb<Route path="/aaa" exact component={AAA} /><Route path="/bbb" exact component={BBB} /></Switch></div></BrowserRouter>

此时,在浏览器中点击两个按钮,应该能看到下方可以切换两种组件啦。


这是最简单的一个路由的实现。在实际的开发中,一般来讲我们会在上方或左侧建立导航栏,通过给导航栏元素添加<Link>来加载页面剩下的内容。听起来有点像iframe?但是路由切换不会像iframe一样直接加载一个页面进来,只是通过路径匹配组件的切换。
当然,实际的开发中我们也不会这么不规范的直接把路由都写在首页里,一般会单写一个router.js文件专门负责路由的控制。在后面的Dva框架中,我们会看到Dva把路由、公用组件、模型文件、服务文件等在创建工程时就帮我们分类好了,这样整个工程结构就非常清晰。

二、Redux管理状态

在前一篇中我们说了,state是react特有的一个存储数据的地方,我们通过各种操作可以改变state的值,然后更新到页面显示上。
但是,当工程变得非常庞大且复杂的时候,各种各样的state和更新state的方法就会使程序变得很乱。在我们后台开发的时候,一向很讲究逻辑对不对,而前后端分离的情况下,管理前端这些数据,我们也需要进行“有条理的对数据进行操作”。
而进行这个操作的,就是Redux
Redux提供一些api来管理数据,Redux很霸道地告诉我们:数据只能存在我这,并且只能通过我的方式来修改!
它包括三部分:storeactionreducer

  • store就像一个有条理的数据库,Redux将整个应用的state储存在唯一的store中。
  • action是……一个有属性的对象,或者说描述了发生了什么的对象,用dispatch(action)来触发(解释:在Dva框架搭建的项目中一般是通过model层来调用dispatch(action)),并且这是改变state的唯一方式
  • reducer是……具体通过action更新state的那个函数,基本结构是,reducer(state, action) => newstate
  • 那么我们继续回到上一篇的那个例子上。比如我们有这样一个表格,现在我们想用Redux的方式做一些更改。(用Antd生成列表请看上一篇https://blog.csdn.net/qq_40241957/article/details/100726297)

    首先要用npm或者yarn装上redux。

    npm install --save redux

    我们大致知道了要创建一个store,并且定义好action和reducer,那么一步一步开始。

    一. 创建store

    第一步在app.js中,引入redux包中的createStore()方法。

    import { createStore } from 'redux';

    然后,通过createStore(reducers[,initialState])的方式来创建store,这个方法根据 reducer生成store,并且只能通过此reducer来改变store中的状态,第二个参数是可选的默认初始值。
    注意,一个应用中我们只有一个store,存储了全部数据状态,但是会有很多reducer,通过这些reducer合起来创建store需要用到combineReducers方法。
    但是我现在只想做一个简单操作,所以用一个reducer做例子

    //初始状态 const initialState = {……data: [{"key": "1","name": "王大斌","gender": "男"},{"key": "2","name": "刘小洋","gender": "男"}]} //创建reducer方法,先原封不动返回state const myreducer = (state=initialState, action) => {return state; } //创建store存储区,它只能通过reducer作为参数来构造 const store = createStore(myreducer);

    这样store就创好了,可以把store打印到控制台看一下。getState()是store的一个最常见api,用了获取state的值。

    console.log("initial state: ", store.getState());


    接下来写一个更新state的action。

    二. 创建action

    Action 是一个带属性的对象,其属性用type来定义,type是必填项,其他的还可以有附带数据,一般写在用payload里。

    //创建描述性对象action const myaction = {type: 'ADD_DATA', payload: { //payload是附带数据的意思 "key": "3","name": "张胖卓","gender": "男"} };

    上面已经说过,修改state的唯一方法就是dispatch(action)(说明:在dva框架中分层开发的时候是一般在model层调用该方法),那么现在我们就把这个action触发一下。

    store.dispatch(myaction);

    如果是点击一个按钮触发的话,把dispatch放在onClick绑定的函数里就行。

    //点击按钮触发 const changeData = () => {store.dispatch(myaction); }class App extends Component {render() {return ( <Button type="primary" onClick={changeData}>修改数据</Button>……);} }

    三. 创建reducer

    Store触发了一个action,相当于store宣称:“我要改变自己的state”,此时,需要reducer来执行这个过程。

    Reducer的输入参数是当前的state和收到的action,他会返回一个新的 state。注意在reducer中,不能随意更改参数或者加入随机性的各种操作,也就是reducer输入相同的话,输出也必定相同。
    我们修改刚刚的reducer如下。

    //创建reducer方法 const myreducer = (state=initialState, action) => {switch (action.type) {case 'ADD_DATA':return {...state, // ...state的作用是把state里的数据以键值对的形式放在这里//下面的一行代码是覆盖原state里的键为“data”的数据data:state.data.concat(action.payload) //在本例中concat()的作用是在原state.data数据的后面连接上payload数据}default: return state;} }

    ...state是ES6中的三点运算符,作用是把数组打开进行操作。
    可以看到,当action是ADD_DATA的时候,我们把payload里面的内容加在原有的data之后,也就是新加一行数据。
    这时,在控制台输出store的值,可以看到已经有所改变。

    console.log("change state: ", store.getState());

    四. 通过监听更新视图

    然而,现在只是store中的值改变了,视图上却没有刷新,。(这个问题纠结了我两天= =)是因为store跟view层并没有连起来,如果不手动重新render,页面是不会变化的,为此我们需要一个监听函数,监听store中值的变化,当发生变化时重新渲染view。
    这个监听由store.subscribe实现。(如果你用了react-redux的话,它里面的connect让我们不需要自己手动去subscribe全局state的变化,它会在内部自动监听并更新。)

    class App extends Component {listerner() {let newState = store.getState();this.setState(newState); }//保持监听componentDidMount () { //下面有代码讲解store.subscribe(this.listerner.bind(this)); //一旦store里的state数据发生变化,就立刻执行这里我们自定义的listener函数来更新view视图展示层} }

    讲解:这样,整个流程实现了:

  • 创建store存储数据,并把初始值绑定到view层。
  • 点击按钮,触发store.dispatch(myaction)。
  • store收到action后,调用myreducer = (state=initialState, action)改变store中的state。
  • store更新后,通过store.subscribe监听函数更新view层。
  • 最终的成果如下:

    虽然很混乱不过总算似乎是实现了整套流程。

    【很重要的补充说明!】

    在上面的例子里,我们只用了redux,事实上在React中,我们一般常用react-redux来进行操作。react-redux提供的结构可以让我们不需要自己手动去写dispatch,subscribe这些函数,它在内部通过自身的结构帮我们完成了这些操作。
    Dva,(终于说到了Dva!),它已经封装好了react-router,react-redux,redux-saga等中间件,并给出了清晰地工程目录结构。因而在了解react基础知识后,用Dva来构建工程更加快捷简便。
    那么,下一篇,我们就来真正用Dva创建一个工程并进行一些简单操作~
    Dva学习文章如下链接:
    https://blog.csdn.net/qq_40241957/article/details/100692742

    本文转载自;https://www.jianshu.com/p/dbf6dda29401

    总结

    以上是生活随笔为你收集整理的Router+Redux学习总结的全部内容,希望文章能够帮你解决所遇到的问题。

    如果觉得生活随笔网站内容还不错,欢迎将生活随笔推荐给好友。