redux基础教程
阅读本文之前,你需要掌握一些基本的react知识,和node的基本环境。
什么是redux?
简单来说,redux就是一个储存数据的仓库。
为什么要学习redux?
当你打开这篇文章的时候,相信你的心中一定有自己的答案,但我还是要啰嗦一下。 学习redux是为了更加方便的管理和获取数据。
我们在用react写代码的时候,为了性能优化和代码规范,一般都会分成组件,但react默认的数据流为单向数据流,所以组件之间的通讯很不方便, 使用reduce之后,就是把所有的数据集中的放在了一个地方,我们就可以在任意组件中获取任意数据了。
如何下载?
到你需要执行项目的文件夹的命令提示面板,执行命令npm i redux -D
如何开始使用?
到这里,算是本篇教程的开始部分了,redux就是一个前端的热门框架,一共分为三部分 action reducers store 先看第一部分
actions
我们先创建一个文件,命名为actionType 里面写你将要执行的动作的类型,可能这么说有一点抽象。 我们以前写react的时候在this.state里面定义的是什么,就可以在actionType里面定义什么 比如:我们想要做一个分页器的功能,先思考一下我们需要储存哪些变量 1.一个总的数据,可能有30条,40条,甚至更多 2.一个我们展示的数据,可能是十条,五条,点击下面的按钮的时候展示的数据发生改变 3.最下面的页码的集合,应该是一个纯Number类型的,从1开始,依次递增的有固定长度的数组。 我们就在actionType里面定义得到这些变量的动作类型,在定义动作类型的时候尽量语义化一点,而且要以大写字母定义,下划线作为连接 变量会发生改变,但是动作类型不会发生改变,所以定义的时候我们直接选用了const来定义
const GET_ALL = 'GET_DATA';
const GET_LIST = 'GET_LIST';
const GTE_PAGE = 'GET_PAGE';
actionType这个文件的作用只是用来定义动作类型的,使用的时候我们需要在别的文件里面使用这些定义的动作类型,所以我们应该把这些动作 类型抛出去,在别的文件中可以访问然后把这个定义之后的常量抛出,因为我们等会要在别的地方使用这个常量
export const GET_ALL = 'GET_DATA';
export const GET_LIST = 'GET_LIST';
export const GTE_PAGE = 'GET_PAGE';
使用redux的目的就是为了管理数据,定义这个常量的名字也是为了得到数据,那么数据应该怎么给仓库呢? 函数里面最方便的办法就是传参了,redux也是
这时候,需要一个新的文件了。 ###reducers 他的作用就是接受一组action和数据,然后返回新的数据 我们先来创建一个文件,命名为reducers 然后,引入我们需要使用的动作类型
import {GET_ALL,GET_LIST,GET_PAGE} from './actionType.js';
这个文件最主要的功能是为了帮忙整理数据,接收一state,之后返回一个state。 仓库要存储的时候,都会先到这个文件里面来转一圈,当没有数据的时候,就会使用这个文件里面的默认值 我们先把数据的默认值定义一下
let initstate = {
all:[],
list:[],
page:[]
}
之后开始进行数据的处理 进行数据处理的时候必须要知道两个参数 1.我的action(定义的动作类型)是什么? 2.要接收的数据 所以这次我们以函数接收参数的方式来处理数据 定义一个函数,接受两个参数,第一个参数为redux内部自己接收的state,第二个参数为我们传递进去的一个对象 对象的type属性写我们要执行的动作类型,text属性是我们要传递给store的参数。 最后把已经改变过了的state抛出去,储存到仓库。
函数里面使用了switch语句是因为每次执行操作的时候,会把定义的函数都执行一遍,为了区分他们的动作类型,不至于每个数据找错自己储存的位置,一般我们在reducers里面定义的函数都是纯函数,所谓纯函数,就是返回结果只依赖它的参数,并且在执行过程没有副作 用的函数。我们赋值的时候为了不影响其他数据,引用类型数据的拷贝都选用深拷贝的方式赋值 let getAll = (state,action){ switch(action.type) { case GET_ALL: state.all=[...action.text]; break; default: break; }; return state.all; }; let getList = (state,action){ switch(action.type) { case GET_LIST: state.list=[...action.text]; break; default: break; }; return state.list; }; let getArr = (state,action){ switch(action.type) { case GET_ARR: state.data=[...action.text]; break; default: break; }; return state.data; }; 观察一下上面这三个函数,他们的返回值分别是什么? 如果action.type符合他们对应case的值,就会返回action.text;否则,就会返回state的默认值initstate的对应属性 所以上面的每一个函数获取的就是对应的initstate里面的每一项的值,我们需要把这些值放在一个对象里面构成新的数据,返回给我们的store;
export default (state,action)=>{
return {
}
}
如果刚开始没有数据的时候接收的就是默认值initstate的值 ,我们这个函数的主要作用就是为了给数据的data的属性赋值,先利用switch语句对action进行判断,如果是我们需要的action就开始进行赋值
前面说了,这个函数主要的功能是为了将数据传给仓库,那么他的返回值就必须是数据了,我们在定义数据的默认值的时候给了一个对象,所以返回的值 也要是一个对象,属性还要一一对应
export default (state = initstate,action){
return {
all:getAll(state,action),
list:getList(state,action),
arr:getArr(state,action)
}
}
我们抛出了一个和默认值属性一样的对象,这个对象中属性的值就是我们上面的函数调用之后的返回值
函数写到现在,剩下的东西已经很清晰明了了,在仓库里面引入这个文件就可以了 我们来建一个名为store的js文件,来进行最后一步的操作
import {createStore} from 'redux';
import reducers from './reducers/reducers.js';
let store = createStore(reducers);
export default store;
createStore是redux封装好的一个方法,顾名思义,创建一个仓库,直接拿来用就好 里面的参数就是我们刚刚写好的要传入仓库中的文件了 然后抛出这个仓库就可以了
实际项目中如何使用?
使用的时候。提前引入store就行了 直接引入使用就可以了
import store from './store.js';
store有两个比较常用的方法
dispatch
store.dispatch();传入数据,里面的参数是一个对象的形式,action和要传入的值 比如 store.dispatch({ type:'GET_ALL', text:data }) data就是我们要存入store的数据 这样就是把数据存在仓库里面了,这个项目中的任意组件就都可以直接得到他的数据了 怎么得到他的数据? 那就是使用它的另一个超级常用的方法啦
getState
store.getState(); 直接打印他得到的就是全部的数据,就是我们之前定义的一个对象的形式 如果想要得到某一条的数据,比如我们刚刚储存进去的data 直接使用store.getState().all就可以得到刚刚储存的数据了。 是不是很简单 什么?
你没有明白,我们来从头再来一遍 我们最开始在actionType里面定义了几个我们需要用的动作类型,然后我们到了reducers文件里面, 给数据定义了一个默认值,写了一个当type类型全等于我们所定义的类型自后给数据赋值的一个函数, 这里要注意这个函数的返回值是一个属性的值,并非是一个对象 之后就是抛出一个函数啦,函数的返回值就是我们最终的数据,所以要和数据默认值的属性一一对应, 最后就是调用createStore,抛出,直接使用就可以了。
是不是觉得好麻烦,还记得我当初学redux的时候看到的一句话 当你不知道是否需要redux的时候,你就是不需要 这只是为了给大家演示写的最简单的一版,算是redux的入门吧