[React] 13 - React-redux

什么情况下需要使用redux

  1. 某个组件的状态,需要让其他组件可以随时拿到(共享)。

  2. 一个组件需要改变另一个组件的状态(通信)。

  3. 总体原则:能不用就不用, 如果不用比较吃力才考虑使用。

 

React Components中的状态  --> 转移到redux那里。所以,状态的改变,地儿变了,让redux 代理去做。

Action就是个包含两个属性的object。

Store不干活,但调度。

Reducers掌管:初始化 state and 更新 state。

 

 

逐步分解

 

纯 react 版本 

$create-react-app redux_test

思路:写了一个组件,其中定义了一个state。若干方法对该state进行算数操作。

...
    state = {count:0}

    //加法
    increment = ()=>{
        const {value} = this.selectNumber
        const {count} = this.state
        this.setState({count:count+value*1})
    }
    //减法
    decrement = ()=>{
        const {value} = this.selectNumber
        const {count} = this.state
        this.setState({count:count-value*1})
    }
    //奇数再加
    incrementIfOdd = ()=>{
        const {value} = this.selectNumber
        const {count} = this.state
        if(count % 2 !== 0){
            this.setState({count:count+value*1})
        }
    }
    //异步加
    incrementAsync = ()=>{
        const {value} = this.selectNumber
        const {count} = this.state
        setTimeout(()=>{
            this.setState({count:count+value*1})
        },500)
    }

    render() {
...

 

 

1)先写store,引入 countReducer。

//引入createStore,专门用于创建redux中最为核心的store对象
import {createStore} from 'redux'
//引入为Count组件服务的reducer
import countReducer from './count_reducer'
//暴露store
export default createStore(countReducer)

 

2)再创建countReducer,实现“动作改变状态”的各种switch流程定义。

const initState = 0 //初始化状态
export default function countReducer(preState=initState, action){
    // console.log(preState);
    //从action对象中获取:type、data
    const {type, data} = action
//根据type决定如何加工数据 switch (type) { case 'increment': //如果是加 return preState + data case 'decrement': //若果是减 return preState - data default: return preState } }

 

3)再开始重新考虑组件,以下是“变化”。

变化3.1,state中的count转移到store管理,其他的部分则可以依然放在这里,例如carName。

state = {carName:'奔驰c63'}

 

变化3.2,发送 action,通过store 转发给 reducer去处理。(action 包含了 用于处理的所有信息:type and data)

increment = ()=>{
    const {value} = this.selectNumber
    const {count} = this.state
    this.setState({count:count+value*1})
}
//加法 increment = ()=>{   const {value} = this.selectNumber   store.dispatch({type:'increment', data:value*1}) // <-- 这种通过参数来控制 动作细节的 可能封装性不太好 }

  

  本质:将state,以及 update state的部分,全都集中在 reducer去“实现”,而store的角色则是”调度“。

 

变化3.3,渲染时,状态只能从 store那里获得。

<h1>当前求和为:{store.getState()}</h1>   // 这里是store的getState,而store里只管理保存了count,而非carName

store中state的任何变化,应该(但不是默认)触发 render。所以,需要如下一行代码在 index.js。

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

 

 

Redux 完整版

集中管理于一个文件。

// count_action.js

/* 该文件专门为Count组件生成action对象 */
import {INCREMENT,DECREMENT} from './constant' export const createIncrementAction = data => ({type:INCREMENT, data}) export const createDecrementAction = data => ({type:DECREMENT, data})

 只是简单地 replaced by functions for 体现redux 的流程图,还有其他的好处么?

// index.js

import React, { Component } from 'react' // 引入store,用于获取redux中保存状态 import store from '../../redux/store' // 引入actionCreator,专门用于创建action对象 import {createIncrementAction,createDecrementAction} from '../../redux/count_action' export default class Count extends Component { state = {carName:'奔驰c63'} /* componentDidMount(){ //检测redux中状态的变化,只要变化,就调用render store.subscribe(()=>{ this.setState({}) }) } */ // 加法 increment = ()=>{ const {value} = this.selectNumber store.dispatch( createIncrementAction(value*1) ) } 。。。
}

 

posted @ 2018-05-18 13:51  郝壹贰叁  阅读(472)  评论(0编辑  收藏  举报