redux:使用工厂函数统一创建action,文件拆分流程

redux


redux是第三方的一个状态管理工具。

先下载npm install --save redux,然后给store对象一个存放位置。
在这里插入图片描述
Redux-创建store的createStore:https://www.jianshu.com/p/53d010fb76d8


一、基础拆分过程

1、数据获取-----------------------

先看下 redux使用、创建基础流程。

>>store.js

// 1、引用createStore,创建store对象
import {createStore} from "redux"

// 4、创建数据
let obj={
    name:"sky",
    age:18
}

// 5、创建reducer 使用纯函数的方式来对数据和修改操作进行关联
// reducer作为一个桥梁 ,负责响应action并修改数据
let reducer=(state=obj,action)=>{
    return state
}

// 2、创建store对象,通过reducer将数据与操作关联起来
let store=createStore(reducer)

// 3、暴露store对象
export default store

全局中取数据,通过store.getState().xxx

>>index.js

import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import * as serviceWorker from './serviceWorker';

// 引入store.js
import store from "./store/store.js"

// 然后在后台打印这个全局下的store
console.log(store);
console.log(store.getState().name);

ReactDOM.render(
  <React.StrictMode>
    <App />
   </React.StrictMode>,
  document.getElementById('root')
);
serviceWorker.unregister();

在这里插入图片描述

组件中取数据,跟全局的方法一样吧,都是store.getState().xxx

>>Bro1.jsx

import React, { Component } from 'react'
// 也是先引入
import store from "../store/store.js"
 
export default class Bro1 extends Component {
    constructor(props) {
        super(props)
        this.state = {
        	// 获取store里的数据
            text: store.getState().name
        }
    }
    render() {
        return (
            <div>
                <h4>I'm big bro1.</h4>
                <p>组件里面从store取数据:{this.state.text}</p>
            </div>
        )
    }
}

在这里插入图片描述

2、数据修改-----------------------
>>Bro1.jsx

import React, { Component } from 'react'
import store from "../store/store.js"

export default class Bro1 extends Component {
    constructor(props) {
        super(props)
        this.state = {
            text: store.getState().age
        }
    } 
    update=()=>{
        // 进行redux的修改  使用dispatch  来进行该修改的分发
        // 若有很多修改动作,通过store.dispatch({type:"调用的任务名--全部大写"})
        store.dispatch({type:"REDUX_UPDATE"})
    }
    componentDidMount() {
    	// subscribe添加一个变化监听器,每当改变store的时候就会执行
        store.subscribe(()=>{
            this.setState({
                text:store.getState().age
            })
        })
    }
    render() {
        return (
            <div>
                <h4>I'm big bro1.</h4>

                <p>组件里面从store取数据:{this.state.text}</p>
                <button onClick={this.update}>点击修改redux中的数据</button>
            </div>
        )
    }
}

在store.js中修改reducer的任务判断

>>store.js

import {createStore} from "redux"
let obj={
    name:"sky",
    age:18
}

let reducer=(state=obj,action)=>{
    // 因为修改会有n个操作,为了方便知道对应修改操作是哪个,
    // 可以通过switch来判断多个修改任务
    switch(action.type){
        case "REDUX_UPDATE":
            return {...state,age:state.age+1} //先用扩展运算符把state展开,当前存储的是obj,就是把obj展开
            break;
        default:
            return state
            break;
    }
}

let store=createStore(reducer)
export default store

在这里插入图片描述

在这里插入图片描述

3、拆分-----------------------
(1)先把 创建数据、创建reducer两部给分离出去,单独成文件。
>>reducer.js

// 把原来的数据和任务都放到这个新建的文件中,方便管理

// 4、创建数据
let obj={
    name:"sky",
    age:18 
}

// 5、创建reducer 使用纯函数的方式来对数据和修改操作进行关联
let reducer=(state=obj,action)=>{
    switch(action.type){
        case "REDUX_UPDATE":
            // return {...state,age:state.age+1} 
            //先用扩展运算符把state展开,当前存储的是obj,就是把obj展开
            return {...state,age:state.age+action.num} //num 是接收到的数据
            break;
        default:
            return state;
            break;
    }
}

export default reducer
>>store.js

import {createStore} from "redux"

// 引入已经拆分出去的数据和任务 ,在reducer.js中
import reducer from "./reducer.js"

let store=createStore(reducer)
export default store

拆分开功能也是可以正常实现的。
在这里插入图片描述

(2)然后把用在页面组件中的任务,也给分离出去,拆分任务名与数据。(就是把原来dispatch的对象单独拿出去)
先拆分数据--------------------
>>actionType.js

let ADD=(val)=>{
    return {type:"REDUX_UPDATE",num:val}
}

export {ADD}
>>Bro1.js

import React, { Component } from 'react'
import store from "../store/store.js"
// 引入拆分出去的任务名和数据
import {ADD} from "../store/actionType.js"

export default class Bro1 extends Component {
    ...
    update=()=>{     
        // store.dispatch({type:"REDUX_UPDATE",num:2})
        // 传过去一个num,在那边可以使用

        // 使用拆分出去的任务名和数据,之前咱们传的num:2,现在也是通过ADD方法来实现
        store.dispatch(ADD(3))
    }
    ...
}

在这里插入图片描述
在这里插入图片描述

再更细一点拆分任务名,这一步看个人需要--------------------
>>acitonName.js

// 拆分任务名
export let REDUX_UPDATE="REDUX_UPDATE";
>>actionType.js

// 引入任务名
import {REDUX_UPDATE} from "./actionName"

let ADD=(val)=>{
    return {type:REDUX_UPDATE,num:val}
}

export {ADD}
>>reducer.js

// 引入任务名
import {REDUX_UPDATE} from "./actionName"

let obj={
    name:"sky",
    age:18
}

let reducer=(state=obj,action)=>{
    switch(action.type){
        case REDUX_UPDATE:
            return {...state,age:state.age+action.num} //num 是接收到的数据
            break;
        default:
            return state
            break;
    }
}

export default reducer

在这里插入图片描述

二、完整拆分流程

完整的应该是把reducer合并再加上。看下面。

先新建一个文件夹storenew,然后创建一个文件storenew.js,然后把reducer独立到reducer.js里面。

>>storenew.js

import {createStore} from "redux"
import reducer from "./reducer.js"

let storenew=createStore(reducer);

export default storenew
>>reducer.js

import tryComReducer from "../compnew/tryComReducer.js"
import {combineReducers} from "redux"

// 合并分散的reducers
let reducer=combineReducers({
    tryComReducer
})

export default reducer

然后咱们再新建一个compnew文件,创建一个组件tryCom.jsx,然后创建一个专属于这个组件的reducer(有点类似于vuex中的数据模块仓库 ),命名为tryComReducer.js 。

>>tryCom.jsx

import React, { Component } from 'react'
import storenew from "../storenew/storenew.js"
import { ADD } from "../storenew/actionType.js"

export default class tryCom extends Component {
    constructor(props) {
        super(props)
        this.state = {
            textname: storenew.getState().tryComReducer.name,
            textage: storenew.getState().tryComReducer.age
        }
    }
    componentDidMount() {
        storenew.subscribe(() => {
            this.setState({
                textage: storenew.getState().tryComReducer.age
            })
        })
    }
  
    fun() {
        storenew.dispatch(ADD(4))
    }
    render() {
        return (
            <div>
                <h4>I'm 尝试store的组件.</h4>
                <p>从store拿到的名字:{this.state.textname}</p>
                <p>从store拿到的年龄:{this.state.textage}</p>

                <button onClick={this.fun}>点击修改</button>
            </div>
        )
    }
}

tryComReducer.js放的是分散的reducer的一个部分。最后这些分散的部分在reducer.js中进行了合并。

>>tryComReducer.js

// 数据  actions的修改操作
import {TRYCOM_ADD} from "../storenew/actionName.js"

let data = {
    name: "susan",
    age: 19
}

let tryComReducer = (state = data, action) => {
    switch (action.type) {
        case TRYCOM_ADD:
            return {...state,age:state.age+action.num}
            break;
        default:
            return state;
            break;
    }
}

export default tryComReducer

其中对修改操作的名字和数据进行了封装。

>>actionType.js

// 将任务名封装的这一步,按自己需要封
// 不过封的话,能够减少名字之间的耦合性
import {TRYCOM_ADD} from "./actionName.js"

export let ADD=(num)=>{
    return {type:TRYCOM_ADD,num}
}
>>actionNamw.js

export let TRYCOM_ADD="TRYCOM_ADD"

涉及到的文件
在这里插入图片描述


总结


这个拆起来看似有点麻烦,但其实,就两大部分:redux中、组件中。

第一部分,拆store对象部分,把store对象中的源数据与动作封装到reducer.js里面,文件名随意定义。然后把分散的reducer模块合并到一个reducer.js文件中,在store创建时把这个reducer给传过去。

第二部分,就是把用在组件中的,修改store中数据的操作给封装起来。把dispatch派发动作和要给store发的参数给单独封起来,为了方便以后的维护,又把任务名也单独封起来了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值