Redux的使用及手写简单版Redux

216 阅读3分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 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对象)