React 只是 DOM 的一个抽象层(ui),并不是 Web 应用的完整解决方案。有两个方面,它没涉及。

 

* 代码结构
* 组件之间的通信

 

为了解决这个问题,2014年 Facebook 提出了 Flux 架构的概念,引发了很多的实现。2015年,Redux 出现,将 Flux 与函数式编程结合一起,很短时间内就成为了最热门的前端架构

 

简单说,如果你的UI层非常简单,没有很多互动,Redux 就是不必要的,用了反而增加复杂性。
* 用户的使用方式非常简单
* 用户之间没有协作
* 不需要与服务器大量交互,也没有使用 WebSocket
* 视图层(View)只从单一来源获取数据



下面情况才是 Redux 的适用场景:多交互、多数据源。
* 用户的使用方式复杂
* 不同身份的用户有不同的使用方式(比如普通用户和管理员)
* 多个用户之间可以协作
* 与服务器大量交互,或者使用了WebSocket
* View要从多个来源获取数据

 

从组件角度看,如果你的应用有以下场景,可以考虑使用 Redux。

 

* 某个组件的状态,需要共享
* 某个状态需要在任何地方都可以拿到
* 一个组件需要改变全局状态
* 一个组件需要改变另一个组件的状态



Redux 的设计思想很简单,就两句话。
1. Web 应用是一个状态机,视图与状态是一一对应的。
2. 所有的状态,保存在一个对象里面(唯一数据源)
 
redux的小案例:理解这个案例就感觉明白了好多;
cnpm i redux -S
```
import {createStore} from 'redux'
import reducer from './reducer'
const Store = createStore(reducer);

export default Store
```
reduers:是一个纯函数Reducer; 函数负责生成 State。由于整个应用只有一个 State 对象,包含所有数据,
import {ADD_NUMBER, REDUCE_NUMBER} from './TYPES'
//创建初始状态
let _state = {
    num:1
}

const reducer = (state = _state,action)=>{
    if(action.type == '@@redux/INIT'){
        console.log('1. Store通过reducer创建了初始状态')
    }
     let _state = Object.assign({},state)
    // alert(action.type)//默认执行的,redux自有的
    //必须有返回值
    switch(action.type){
      
        case ADD_NUMBER:
          console.log('6.reducer接收到action并根据信息判断知乎返回新的state')
            _state.num ++;
            return _state;break;
        case REDUCE_NUMBER:
          
            _state.num --;
            return _state;break;
        default:
           return state;break;
    }
    return state
}

export default reducer


cnpm i redux -S
counter:计数器

```
import React from 'react';
import PropTypes from 'prop-types';
import Store from '../redux/store'
import Button from './Button'
//调用actions中的方法
import actions from '../redux/actions'
class Counter extends React.Component{
    constructor(props){
        super(props)

        this.state = {
             num:Store.getState().num
        }
            console.log('2.view通过Store.getState()获取到了store挂在在自己的状态')
            this.handleAddNumber = this.handleAddNumber.bind(this)
            // this.handleReduceNumber = this.handleReduceNumber.bind(this)
    }
    handleAddNumber(){
        console.log('3.用户产生了操作调用了action方法')
         actions.addNumber()
    }
    // handleReduceNumber(){
    //     actions.reduceNumber()
    // }
    componentWillMount(){
        Store.subscribe(function(){
            console.log('7.store的reducer更改为新的state的时候,store.subscribe方法里的回调函数会执行,此时就可以通知view去重新获取state')
            this.setState({num:Store.getState().num})
        }.bind(this))
    }
    render(){
        let {num} = this.state
        return(
            <div>
                <Button handler = {actions.reduceNumber}>-</Button>
                {num}
                <Button handler = {this.handleAddNumber}>+</Button>
            </div>
        )
    }
}
Counter.defaultProps = {

}
Counter.propTypes = {

}

export default Counter
action:是一个穿对象,包含一些方法;

```
import {ADD_NUMBER,REDUCE_NUMBER} from './TYPES'
//需要调用store的方法
import Store from './store'
//纯对象,包含一些方法
const actions = {
    
  addNumber(){
      console.log('4.actions的方法被调用,创建了带有标示信息的action')
      let action = {
           type:ADD_NUMBER
      }
          console.log('5.actions同故调用actions.dispatch方法传递给reducer')
      Store.dispatch(action)
  },
 reduceNumber(){
        let action = {
            type:REDUCE_NUMBER
        }
        Store.dispatch(action)
    }
        
   
    //发送给store
  
}
export default actions
TYPES:

```
const ADD_NUMBER = 'ADD_NUMBER'
const REDUCE_NUMBER = 'REDUCE_NUMBER'
export {ADD_NUMBER,REDUCE_NUMBER}
```
注意:flux,redux都不是必须和react搭配使用的,因为flux和redux使完整的架构,在学习react的时候,只是将


Reducer 函数最重要的特征是,它是一个纯函数。也就是说,只要是同样的输入,必定得到同样的输出。
纯函数是函数式编程的概念,必须遵守以下一些约束。
* 不得改写参数
* 不能调用系统 I/O 的API
* 不能调用Date.now()或者Math.random()等不纯的方法,因为每次会得到不一样的结果;可以放在action里进行操作

划分reducer

因为一个应用中只能有一个大的state,这样的话reducer中的代码将会特别特别的多,那么可以使用combineReducers方法将已经分开的renducer合并到一起
```
// State 是一个数组
function reducer(state, action) {
return [...state, newItem];
}
```

最好把 State 对象设成只读。你没法改变它,要得到新的 State,唯一办法就是生成一个新对象。这样的好处是,任何时候,与某个 View 对应的 State 总是一个不变的对象。

注意:
1. 分离reducer的时候,每一个reducer维护的状态都应该不同

2. 通过store.getState获取到的数据也是会安装reducers去划分的
无状态组件里含有react
posted on 2018-01-23 20:16  Anby-PBH  阅读(153)  评论(0)    收藏  举报