React07---redux

烂漫一生 提交于 2020-01-29 00:58:32

Redux:不是react,更多的用在react里面,管理react应用中多个组件共享
Redux工作流程:
在这里插入图片描述
什么情况需要redux:

  1. 总体原则: 能不用就不用, 如果不用比较吃力才考虑使用
  2.  某个组件的状态,需要共享
    
  3.  某个状态需要在任何地方都可以拿到
    
  4.  一个组件需要改变全局状态
    
  5.  一个组件需要改变另一个组件的状态
    

未拆分成redux的app.jsx

import React,{Component} from 'react'
export default class App extends Component{
    state = {
        number:0
    }
    Add = () =>{
        // console.log(this.select.value);
        let count = this.select.value*1;
        let number = this.state.number;
        this.setState({number:number+count});
    }
    Der = () =>{
        // console.log(this.select.value);
        let count = this.select.value*1;
        let number = this.state.number;
        this.setState({number:number-count});
    }
    Odd = () =>{
        // console.log(this.select.value);
        let count = this.select.value*1;
        let number = this.state.number;
        if(number%2 === 1){
            this.setState({number:number+count});
        }
    }
    Ancy = () =>{
        // console.log(this.select.value);
        let count = this.select.value*1;
        let number = this.state.number;
        setTimeout(()=>{
            this.setState({number:number+count});
        },1000);
    }
    render(){
        return(
            <div>
                <p>Click {this.state.number} times</p>
                <div>
                    <select name="" id="" ref={select => this.select = select}>
                        {/* 这里用的非可控组件获取value,我的理解是将select放到this中,之后再用this.来取,来做到相同组件内的交互
                            但是不同于this.state.****,这个是放到state中,但是非可控组件不需要。也不同于父组件向子组件传值用props

                            于是目前为止有了三种传值方式:
                            1.this.***
                            2.this.state.***
                            3.this.props.***
                            */}
                        <option value="1">1</option>
                        <option value="2">2</option>
                        <option value="3">3</option>
                    </select>
                </div>
                <button onClick={this.Add}>+</button>&nbsp;
                <button onClick={this.Der}>-</button>&nbsp;
                <button onClick={this.Odd}>奇数</button>&nbsp;
                <button onClick={this.Ancy}>异步</button>
            </div>
        )
    }
}

运行截图:
在这里插入图片描述

Redux版本:
Store对象

  1. 编码
    import {createStore} from ‘redux’
    import counter from ‘./reducers/counter’
    const store = createStore(counter)
  2. 作用:redux库的核心的管理对象
  3. 它内部维护着:state、reducer
  4. 核心方法:
    getState()
    dispatch(action)
    subscribe(listener)
  5. 编码
    store.getState()
    store.dispatch({type:‘INCREMENT’, number})
    store.subscribe(render)

redux的核心概念
8.3.1. action

  1. 标识要执行行为的对象
  2. 包含2个方面的属性
    a. type: 标识属性, 值为字符串, 唯一, 必要属性
    b. xxx: 数据属性, 值类型任意, 可选属性
  3. 例子:
    const action = {
    type: ‘INCREMENT’,
    data: 2
    }
  4. Action Creator(创建Action的工厂函数)
    const increment = (number) => ({type: ‘INCREMENT’, data: number})
    8.3.2. reducer
  5. 根据老的state和action, 产生新的state的纯函数
  6. 样例
    export default function counter(state = 0, action) {
    switch (action.type) {
    case ‘INCREMENT’:
    return state + action.data
    case ‘DECREMENT’:
    return state - action.data
    default:
    return state
    }
    }
  7. 注意
    a. 返回一个新的状态
    b. 不要修改原来的状态
    8.3.3. store
  8. 将state,action与reducer联系在一起的对象
  9. 如何得到此对象?
    import {createStore} from ‘redux’
    import reducer from ‘./reducers’
    const store = createStore(reducer)
  10. 此对象的功能?
    getState(): 得到state
    dispatch(action): 分发action, 触发reducer调用, 产生新的state
    subscribe(listener): 注册监听, 当产生了新的state时, 自动调用
    第一步:生成 store对象
    在这里插入图片描述
    第二步:创建reducers对象,每一个reducers就是一个函数
    在这里插入图片描述
    第三步,关联reducers和store

第四步,修改app.jsx,store里面有getState()方法用来取默认值、dispatch()方法用来修改值。
在这里插入图片描述

  1. 传入store到app.jsx
    在这里插入图片描述
  2. 修改app.jsx里面的方法
    在这里插入图片描述
  3. 最后发布更新
    在这里插入图片描述

源码:
index.js

import React from 'react'
import ReactDOM from 'react-dom'
import App from './components/app'

import {createStore} from 'redux'
import {counter} from './redux/reducers'

//生成一个store对象,在createStore()里面关联reducers里面的函数
const store = createStore(counter);// 内部会第一次调用reducer函数得到初始的state=0,
                                    //等于零是因为在reducers里面已经赋予了state形参默认值
console.log(store);
function render(){
    ReactDOM.render(<App store={store}></App> , document.getElementById('root'));
}
//初始化渲染
render();
//订阅监听
store.subscribe(render);

reducers.jsx:

/*
这是一个包含n个reducer的模块
注:一个模块只有一个default
*/
import {INCREMENT,DECREMENT} from './action-type'
export function counter(state=0,action){//形参默认值
    // console.log(state+""+action);
    switch(action.type){
        case INCREMENT:
            return state + action.data;
        case DECREMENT:
            return state - action.data;
        default:
            return state;
    }
}

app.jsx:

import React,{Component} from 'react'
import {INCREMENT,DECREMENT} from '../redux/action-type'
export default class App extends Component{
    Add = () =>{
        // console.log(this.select.value);
        let count = this.select.value*1;
        //调用store的方法来更新状态,用dispatch()
        this.props.store.dispatch({type:INCREMENT,data:count});
    }
    Der = () =>{
        // console.log(this.select.value);
        let count = this.select.value*1;
        // let number = this.state.number;
        // this.setState({number:number-count});
        this.props.store.dispatch({type:DECREMENT,data:count});
    }
    Odd = () =>{
        // console.log(this.select.value);
        let count = this.select.value*1;
        // let number = this.state.number;
        let number = this.props.store.getState();
        if(number%2 === 1){
            this.props.store.dispatch({type:INCREMENT,data:count});
        }
    }
    Ancy = () =>{
        // console.log(this.select.value);
        let count = this.select.value*1;
        let number = this.state.number;
        setTimeout(()=>{
            this.props.store.dispatch({type:INCREMENT,data:count});
        },1000);
    }
    render(){
        //得到store里面的默认值
        // console.log(this.props.store.getState());
        const count = this.props.store.getState();
        console.log(count);
        return(
            <div>
                <p>Click {count} times</p>
                <div>
                    <select name="" id="" ref={select => this.select = select}>
                        {/* 这里用的非可控组件获取value,我的理解是将select放到this中,之后再用this.来取,来做到相同组件内的交互
                            但是不同于this.state.****,这个是放到state中,但是非可控组件不需要。也不同于父组件向子组件传值用props

                            于是目前为止有了三种传值方式:
                            1.this.***
                            2.this.state.***
                            3.this.props.***
                            */}
                        <option value="1">1</option>
                        <option value="2">2</option>
                        <option value="3">3</option>
                    </select>
                </div>
                <button onClick={this.Add}>+</button>&nbsp;
                <button onClick={this.Der}>-</button>&nbsp;
                <button onClick={this.Odd}>奇数</button>&nbsp;
                <button onClick={this.Ancy}>异步</button>
            </div>
        )
    }
}

action-type.jsx:

/*
    包含所有action type的常量字符串
*/
export const INCREMENT = 'INCREMENT';
export const DECREMENT = 'DECREMENT';
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!