求和案例(redux精简版)

文章目录

  • redux简介
  • 求和案例(redux精简版v1)
    • redux/store.js
    • redux/reducer.js
    • Counter/index.jsx(Counter组件)
  • 求和案例(redux精简版v2)
    • redux/store.js
    • redux/reducer.js
    • Counter/index.jsx(Counter组件)
    • 入口文件index.js
  • 相关链接

redux简介

redux是一个专门用作状态管理的js库,不是react的插件库。它可用于react、angular、vue等项目,但基本与react配合使用。

redux的三个核心概念:

  1. actionaction是一个普通的js对象,包含以下两个属性:
    type:是一个必选属性,值是一个字符串,且必须唯一,它标识了动作类型。
    data:是一个可选属性,值可以是任意类型。
  2. reducerreducer是一个纯函数,用于初始化状态、加工状态。加工状态时,将根据旧的state和action,返回一个新的state。
  3. storestore将state、action、reduce联系在一起,它提供如下API,
    store.getState(),获取state。
    store.dispatch(action),派发action。
    store.subscribe(callback),监听store中的state的变化。

求和案例(redux精简版v1)

求和案例(redux精简版)_第1张图片
本篇将使用redux实现求和案例。

首先,npm install --save redux,安装redux库。

然后,此次代码变更涉及的文件有:

  1. redux/store.js。在src下新建文件夹:redux,redux下新建文件:store.js。
  2. redux/reducer.js。redux下新建文件:reducer.js。
  3. component/Counter/index.jsx,即Counter组件。

redux/store.js

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

export default createStore(counterReducer);

createStore(),用于创建store对象。整个应用只有一个store对象。

redux/reducer.js

const initState = 0

export default function reducer(preState=initState,action){
    const {type,data} = action;
    switch(type){
        case "increment": return preState+Number(data);
        case "decrement": return preState-Number(data);
        default: return preState
    }
}

reducer实质是一个函数,它接受两个参数:

  1. preState,即旧的状态数据。
  2. action,即action对象。reducer将根据动作类型,即type,决定如何加工数据。

Counter/index.jsx(Counter组件)

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

export default class Counter extends Component {

    componentDidMount(){
        store.subscribe(() => {
            this.setState({})
        })
    }

    increment = () => {
        const {value} = this.selectEl;
        store.dispatch({
            type:"increment",
            data:Number(value)
        })
        
    }
    decrement = () => {
        const {value} = this.selectEl;
        store.dispatch({
            type:"decrement",
            data:Number(value)
        })

    }
    incrementOdd = () => {
        const {value} = this.selectEl;
        const count = store.getState();
        if(count % 2 !== 0){
            store.dispatch({
                type:"increment",
                data:Number(value)
            })
        }
    }
    incrementWait = () => {
        const {value} = this.selectEl;  
        setTimeout(() => {
            store.dispatch({
                type:"increment",
                data:Number(value)
            })
        },1000)
    }

  render() {
    const {increment,decrement,incrementOdd,incrementWait} = this;
    return (
        <div>
            <h2>当前求和为{store.getState()}</h2>
            <select ref={c => this.selectEl = c}>
                <option value="1">1</option>
                <option value="2">2</option>
                <option value="3">3</option>
            </select>&nbsp;
            <button onClick={increment}>+</button>&nbsp;
            <button onClick={decrement}>-</button>&nbsp;
            <button onClick={incrementOdd}>和为奇数时加</button>&nbsp;
            <button onClick={incrementWait}>等一等再加</button>
        </div>
    )
  }
}

store.subscribe(()=>{callback}) 将监听store中的state是否发生变化,如果state变化,将执行对应回调。本例中,一旦state发生变化,将调用this.setState({})来实现页面的重新渲染。

求和案例(redux精简版v2)

求和案例(redux精简版)_第2张图片

求和案例(redux精简版v2)、 求和案例(redux精简版v1)的区别在于:store.subscribe()不放在Counter组件(Counter/index.jsx)里,而是放在入口文件index.js里。

此次变更涉及的文件有:

  1. redux/store.js
  2. redux/reducer.js
  3. components/Counter/index.jsx,即Counter组件
  4. 入口文件index.js

redux/store.js

同上。

redux/reducer.js

同上。

Counter/index.jsx(Counter组件)

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

export default class Counter extends Component {

    increment = () => {
        const {value} = this.selectEl;
        store.dispatch({
            type:"increment",
            data:Number(value)
        })
        
    }
    decrement = () => {
        const {value} = this.selectEl;
        store.dispatch({
            type:"decrement",
            data:Number(value)
        })

    }
    incrementOdd = () => {
        const {value} = this.selectEl;
        const count = store.getState();
        if(count % 2 !== 0){
            store.dispatch({
                type:"increment",
                data:Number(value)
            })
        }
    }
    incrementWait = () => {
        const {value} = this.selectEl;  
        setTimeout(() => {
            store.dispatch({
                type:"increment",
                data:Number(value)
            })
        },1000)
    }

  render() {
    const {increment,decrement,incrementOdd,incrementWait} = this;
    return (
        <div>
            <h2>当前求和为{store.getState()}</h2>
            <select ref={c => this.selectEl = c}>
                <option value="1">1</option>
                <option value="2">2</option>
                <option value="3">3</option>
            </select>&nbsp;
            <button onClick={increment}>+</button>&nbsp;
            <button onClick={decrement}>-</button>&nbsp;
            <button onClick={incrementOdd}>和为奇数时加</button>&nbsp;
            <button onClick={incrementWait}>等一等再加</button>
        </div>
    )
  }
}

入口文件index.js

import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';

import store from "./redux/store.js";

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

store.subscribe(() => {
    ReactDOM.render( <App />,document.getElementById("root"));
})

相关链接

求和案例(纯react版本)

你可能感兴趣的:(React17/18,react,求和案例,redux)