redux的使用

1.redux的使用

核心概念

action

  1. 动作的对象

  2. 包含2个属性

    type:标识属性, 值为字符串, 唯一, 必要属性
    data:数据属性, 值类型任意, 可选属性
    
  3. 例子:{ type: 'ADD_STUDENT',data:{name: 'tom',age:18} }

reducer

  1. 用于初始化状态、加工状态。

  2. 加工时,根据旧的state和action, 产生新的state的纯函数

store

  1. 将state、action、reducer联系在一起的对象

  2. 如何得到此对象?

    1)   import {createStore} from 'redux'
    
    2)   import reducer from './reducers'
    
    3)   const store = createStore(reducer)
    
  3. 此对象的功能?

    1)   getState(): 得到state
    
    2)   dispatch(action): 分发action, 触发reducer调用, 产生新的state
    
    3)   subscribe(listener): 注册监听, 当产生了新的state时, 自动调用
    

求和案例使用redux

constant.js

/*
    该模块是用于定义actions对象中type类型的常量值
 */

export const INCREMENT = 'increment'
export const DECREMENT = 'decrement'

count_action.js

/*
    该文件专门为Count组件生成action对象
 */
import {INCREMENT, DECREMENT} from "./constant";


export const createIncrementAction = data => ({type: INCREMENT, data})

export const createDecrementAction = data => ({type: DECREMENT, data})

count_reducer.js

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


const initState = 0 //初始化状态,页面渲染时会自动调用一次
export default function countReducer(preState=initState, action) {
    console.log(preState, action)
    // 从action对象中获取type,data
    const {type, data} = action
    // 根据type决定如何加工数据
    switch (type) {
        case INCREMENT: // 如果是加
            return preState + data;
        case DECREMENT: // 如果是减
            return preState - data;
        default:
            return preState
    }
}

store.js

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

// 引入createStore, 专门用于创建redux中最核心的store对象
import {createStore} from "redux";
// 引入为Count组件服务的reducer
import count_reducer from "./count_reducer";

export default createStore(count_reducer)

index.js

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中状态的变化,只要变化,就调用render
store.subscribe(()=>{
      ReactDOM.render(<App />, document.getElementById('root'))
})

Count.jsx

import React, {Component} from 'react';
// 引入store, 用于获取redux保存的状态
import store from "../../redux/store";
// 引入actionCreator, 专门用于创建action对象
import {createDecrementAction, createIncrementAction} from "../../redux/count_action";


class Count extends Component {

    state = {count: 0}

    // 第二种方法:第一种在index.js订阅
    // componentDidMount() {
    //     // 监测redux中状态的变化,只要变化,就调用render
    //     store.subscribe(()=>{
    //         this.setState({})
    //     })
    // }

    increment = () => {
        const {value} = this.selectNumber
        store.dispatch(createIncrementAction(value*1))
    }
    decrement = () => {
        const {value} = this.selectNumber
        store.dispatch(createDecrementAction(value*1))

    }
    incrementOdd = () => {
        const {value} = this.selectNumber
        const count = store.getState()
        if (count % 2 !== 0) {
            store.dispatch(createIncrementAction(value*1))
        }
    }
    incrementAsync = () => {
        const {value} = this.selectNumber
        setTimeout(() => {
            store.dispatch(createIncrementAction(value*1))
        }, 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>
                <button onClick={this.increment}>+</button>
                <button onClick={this.decrement}>-</button>
                <button onClick={this.incrementOdd}>当前求和为奇数加</button>
                <button onClick={this.incrementAsync}>异步加</button>
            </div>
        );
    }
}

export default Count;

异步action版

npm install --save redux-thunk (需安装使用异步中间件)

store.js中修该

import {createStore, applyMiddleware} from "redux";
// 引入redux-thunk,用于支持异步action
import thunk from "redux-thunk";

// applyMiddleware使用中间件
export default createStore(count_reducer, applyMiddleware(thunk))

count_action.js中修改

import {INCREMENT, DECREMENT} from "./constant";

// 同步action: 就是指action的返回值为Object类型的一般对象
export const createIncrementAction = data => ({type: INCREMENT, data})

export const createDecrementAction = data => ({type: DECREMENT, data})

// 异步action: 就是指action的返回值为函数,函数自动接收dispatch
// 异步action中一般都会调用同步action,异步action不是必须要用的
export const createIncrementAsyncAction = (data, time) => {
    return (dispatch)=>{
         setTimeout(()=>{
            dispatch(createIncrementAction(data))
         },time)
    }
}
posted @ 2021-09-03 16:54  tomjoy  阅读(117)  评论(2编辑  收藏  举报