Redux数据集中管理

一、滤清关系

React : 前端语言框架
Redux :状态集中管理的架构
React-Redux:React 专用进行状态集中管理的库
首先Redux 跟React 没有关系,他俩是两个不同公司的产物,当然Vue中也可以使用redux,但是大家都习惯在vue项目中用vuex来集中管理。
redux是2014年 Facebook 提出了 Flux 架构的概念,引发了很多的实现。2015年,Redux 出现,将 Flux 与函数式编程结合一起,很短时间内就成为了最热门的前端架构。
当react的作者看到越来越多的人在react项目中使用redux,为了方便使用,Redux 的作者封装了一个 React 专用的库 React-Redux来进行状态集中管理。
至此 这就是React 、Redux 、React-Redux的关系,本文着重介绍Redux

二、react原理图

在这里插入图片描述

大白话讲解原理图:

假设一个饭店就餐的场景,项目中各个组件(Components)就相当于来饭店就餐的顾客,Rudex整体就相当饭店,此时顾客将看完菜单直接叫服务员(Actions)过来点餐,点了一份老干妈炒饭,服务员收到后转身来到前台老板(Store)这里,告诉老板客人点了什么(type:‘炒饭’ data:‘老干妈炒饭’),老板听到在点餐机上输入告诉后厨(Reducers)来一份老干妈炒饭,随后后厨开始制作,做好之后给老板端过去,客人来老板这取餐。
当然如果饭店规模小,可以不需要服务员(Actions),顾客(Components)点完餐直接告诉饭店老板(Store),随后老板告诉厨师(Reducers)。

三、搭建步骤

1.安装
npm install redux --save
2.在项目src下新建redux文件夹

----redux 文件夹
   ----store.js文件
   ----actions文件夹(放各个组件的action.js文件)
   ----reducers文件夹(放各个组件的reducer.js文件)

store.js中所要做的事:

1)引入redux中的createStore函数,创建一个store
2).createStore调用时要传入一个为其服务的reducer
3).记得暴露store对象,因为其他地方需要引入store
4).需要异步action时,先安装 npm add redux-thunk ;

/* 
	该文件专门用于暴露一个store对象,整个应用只有一个store对象
*/

//引入createStore,专门用于创建redux中最为核心的store对象
//引入applyMiddleware,执行中间件
import {createStore,applyMiddleware} from 'redux'
//引入汇总之后的reducer
import reducer from './reducers'
//引入redux-thunk,中间件 用于支持异步action
import thunk from 'redux-thunk'

//暴露store 
export default createStore(reducer, applyMiddleware(thunk))

action中所要做的事:

首先在 actions文件夹下新建各个组件的action文件

--- count.js (该文件用于专门为Count组件生成action对象)
---person.js(该文件用于专门为Person组件生成action对象)

以count为例


//同步action,就是指action的值为Object类型的一般对象
export const increment = data => ({type:'jia',data})
export const decrement = data => ({type:'jian',data})

//异步action,就是指action的值为函数,异步action中一般都会调用同步action,异步action不是必须要用的。
export const incrementAsync = (data,time) => {
	return (dispatch)=>{
		setTimeout(() => {
			dispatch(increment(data))
		},time)
	}
}

何时需要异步action:想要对状态进行操作,但是具体的数据靠异步任务返回
1)npm add redux-thunk 并配置在store中
2)创建action的函数不再返回一般对象,而是一个函数,该函数中写异步任务
3)异步任务有结果后发布一个同步action去真正操作数据

reducers中所要做的事:

首先在 reducers文件夹下新建各个组件的reducer文件
action文件 中
1.该文件是用于创建一个为组件服务的reducer,reducer的本质就是一个函数
2.reducer函数会接到两个参数,分别为:之前的状态(preState),动作对象(action)

--- count.js (该文件用于创建一个为Count组件服务的reducer)
---person.js (该文件用于创建一个为Person组件服务的reducer)
--- ......(各个组件的reducer)
--- index.js (该文件用于汇总所有的reducer为一个总的reducer)

组件里还是以count 为例

/* 
	1.该文件是用于创建一个为Count组件服务的reducer,reducer的本质就是一个函数
	2.reducer函数会接到两个参数,分别为:之前的状态(preState),动作对象(action)
*/

const initState = 0 //初始化状态
export default function countReducer(preState=initState,action){
	//从action对象中获取:type、data
	const {type,data} = action
	//根据type决定如何加工数据
	switch (type) {
		case 'jia': //如果是加
			return preState + data
		case 'jian': //若果是减
			return preState - data
		default:
			return preState
	}
}

index.js 文件进行汇总所有的reduce

/* 
	该文件用于汇总所有的reducer为一个总的reducer
*/
//引入combineReducers,用于汇总多个reducer
import {combineReducers} from 'redux'
//引入为Count组件服务的reducer
import count from './count'
//引入为Person组件服务的reducer
import persons from './person'

//汇总所有的reducer变为一个总的reducer
export default  combineReducers({
	count,
	persons
})

具体组件中使用

以count组件 为例

import React, { Component } from 'react'
//引入store,用于获取redux中保存状态
import store from '../../redux/store'
//引入actionCreator,专门用于创建action对象
import {
	increment,
	decrement,
	incrementAsync
} from '../../redux/count_action'

export default class Count extends Component {

	state = {carName:'奔驰c63'}

	//加法
	increment = ()=>{
		const {value} = this.selectNumber
		store.dispatch(increment(value*1))
	}
	//减法
	decrement = ()=>{
		const {value} = this.selectNumber
		store.dispatch(decrement(value*1))
	}
	//异步加
	incrementAsync = ()=>{
		const {value} = this.selectNumber
		// setTimeout(()=>{
			store.dispatch(incrementAsync(value*1,500))
		// },500)
	}

	render() {
		return (
			<div>
				<h1>当前求和为:{store.getState()}</h1>
				<select ref={c => this.selectNumber = c}>
					<option value="1">1</option>
					<option value="2">2</option>
					<option value="3">3</option>
				</select>&nbsp;
				<button onClick={this.increment}>+</button>&nbsp;
				<button onClick={this.decrement}>-</button>&nbsp;
				<button onClick={this.incrementAsync}>异步加</button>&nbsp;
			</div>
		)
	}
}

项目根文件index.js 文件中所要做的事:

在index.js中监测store中状态的改变,一旦发生改变重新渲染
备注:redux只负责管理状态,至于状态的改变驱动着页面的展示,要靠我们自己写。

import React from 'react'
import ReactDOM from 'react-dom'
import App from './App'
import store from './redux/store'

ReactDOM.render(<App/>,document.getElementById('root'))

//监测redux中状态的改变,如redux的状态发生了改变,那么重新渲染App组件
store.subscribe(()=>{
	ReactDOM.render(<App/>,document.getElementById('root'))
})

不用担心某一个组件数据状态发生变化,整个项目都要重新渲染的问题,因为react的底层diff算法会帮我们处理好。

至此 我们就可以愉快的在项目中使用redux啦

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值