持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第6天,点击查看活动详情
1.安装
npm i redux
2.创建
新建store.js文件,使用redux方法createStore创建store,并将reducer传入,reducer包含两个参数,prevState是初始数据,action是对store进行的操作,通过action.type获取不同的操作,从而对数据进行相对应操作,最后返回对应数据。 store.js
import {createStore} from 'redux'
const reducer=(prevState,action)=>{
const newdata={...prevState}
switch (action.type){
case 'change':
newdata.number=1
return newdata
default:
return newdata
}
}
const store=createStore(reducer)
export default store
在组件中,利用store.dispatch将操作推入store中,在reducer中执行相应操作。 component
import React, { Component } from 'react'
import store from '../redux/store'
export default class center extends Component {
componentDidMount(){
store.subscribe(()=>{
console.log(store.getState())
})
}
render() {
return (
<div>
<div onClick={()=>{this.handleChange()}}>修改</div>
</div>
)
}
handleChange(){
store.dispatch({
type:'change'
})
}
}
3.手写简单版redux(发布订阅模式)
手写简单版redux就是利用订阅发布模式
首先我们定义一个函数createStore用于创建store实例
在createStore中,定义list用于存放订阅者的回调函数
定义subscribe方法,用于将订阅者的回调函数推入list数组中
定义dispatch方法,用于收集操作,并且调用reducer函数,对数据进行对应操作后将数据赋值给内部闭包数据state
其次定义getState函数用于获取我们的内部闭包数据
最后我们将subscribe、dispatch、getState返出,用于实例调用。
// import {createStore} from 'redux'
const reducer=(prevState={},action)=>{
const newdata={...prevState}
switch (action.type){
case 'change':
newdata.number=1
return newdata
default:
return newdata
}
}
function createStore(reducer){
let list =[];
let state=reducer(undefined,[]);
function subscribe(callback){
list.push(callback)
}
function dispatch(action){
state=reducer(state,action)
for(var i in list){
list[i] && list[i]()
}
}
function getState(){
return state
}
return {
subscribe,
dispatch,
getState
}
}
const store=createStore(reducer)
export default store
4.Redux-reducer合并
如果不同的action所处理的属性之间没有联系,我们可以把reducer函数拆分,不同的函数处理不同的属性,最终合并成一个大的reducer即可。
import {combineReducers} from 'redux
import Areducer from './Areducer'
import Breducer from './Breducer'
const reducer=combineReduces({
Areducer
Breducer
})
const store=createStore(reducer)
export default store
const Areducer=(prevState,action)=>{
const newdata={...prevState}
switch (action.type){
case 'change':
newdata.number=1 //action处理属性不同
return newdata
default:
return newdata
}
}
export Areducer
不同reducer必须处理不同的属性
5.Redux中间件-redux-thunk
在redux中,action仅仅携带了数据的普通js对象,action creator返回值是这个action类型的对象,然后通过store.dispatch()进行分发,但是reducer无法处理异步情况,我们需要在action和reducer中搭建起一座桥梁来处理异步,这就是middleware
- (1)中间件的由来与原理机制
export default function thunkMiddleware({dispatch,getState}){
return next =>action=>{
typeof action === 'function'?
action(dispatch,getState):next(action);
}
}
中间件接收到参数action,如果不是function则和过去一样执行next方法进行下一步处理,如果是function,则先执行action,action的处理结束之后,在action的内部调用dispatch。
-(2)常用异步中间件 a.redux-thunk(store.dispatch参数可以是一个function)
// store
import thunk from 'redux-thunk'
import {applyMidddleware} from 'redux'
import Areducer from './Areducer'
import Breducer from './Breducer'
const reducer=combineReduces({
Areducer
Breducer
})
const store=createStore(reducer,applyMidlleware(thunk))
// 页面中
useEffect(()=>{
store.dispacth(getList())
})
//方法中
const getList=()=>{
// 异步请求 中间件会将dispatch,store传入回调函数中
return (dispatch,store){
axios().then((res)=>{
dispatch({
type:'change',
list:res.result
})
})
}
}
-(2)常用异步中间件 a.redux-promise(store.dispatch参数可以是一个promise对象)