4.Redux (这篇文章需要修改)

安装: npm install --save redux react-redux redux-thunk
参考地址:https://www.jianshu.com/p/06f5285e2620

Redux:

  reduce + flux ( 是一个可预测的状态管理容器。)

Redux 三大原则:
  1.整个应用的 state 被存储在一棵 object tree 中,并且这个 object tree 
  只存在于唯一一个 store 中

  2.state 是只读的,唯一改变 state 的方法基于是触发 action,action 是
  一个用于描述已发生事件的普通对象使用纯函数来执行修改,为了描述
  action 如何改变 state tree,你需要编写 reducers

  3.单一数据源的设计让 react 的组件之间的通信更加方便,同时也便于状态统一管理

三大核心:
  reducer 必须传入一个纯函数
  action 要处理哪个逻辑
  store 联系和管理

  state 就为初始化数据
  action 要处理哪个逻辑
  reducer
    function reducer(state={num:0},action){
      switch(action.type){
        case "ADD":
          let state = Object.assgin({},state);
          state.num ++;
        return state; //state 为新的地址
      }
    }
 
store:就是保存数据的地方,你可以把它看成一个仓库(容器)。整个应用只有一个 store
  const store = createStore(reducer);
 
reducer:(管理员 机制)必须是个纯函数,所有的状态更改都要经过reducer,基于不同的行为标识,修改store中不同的状态
  纯函数 -> 对于任何相同的输入有着相同的输出结果
  简单来说:
    每次发起了 action,action 处理之后的结果为新地址的 state
  //STATE:
  //ACTION:
  function reducer(state,action){
    switch(action.type){
      case "ADD":
        let state = Object.assgin({ },state);
        state.num ++;
      return state; //state为新的地址(返回的值会把原始STORE中的状态信息替换掉)
    }
  }
 
store.dispatch({type:'ADD'})  发起一个action(action:传进来的行为)
store.getState()  读取状态数据
store.subscribe(()=>{})  向事件池中追加方法,当STORE中的状态改变,强制更新当前组件(能监听(订阅)状态的变化(只要状态发生了变化,就执行subscribe的方法))


react-redux   基于redux开发的更适用于react中的状态管理插件。(2019-2-22,周老师)

  Provider 必须在顶层   
    import {Provider} from 'react-redux';
 
  有 router 有 redux 就是
    <Provider>
      <Router>
        <App/>
      </Router>
    </Provider>

  只有 redux
    <Provider>
      <App/>
    </Provider>

 
使用 react-redux + redux 的内功心法。

  1.引包 react-redux 中的 Provider,redux 中的 createStore
    import { Provider } from " react-redux "
    import { cteateStore } from " redux "

  2.创建 store
    const store = createStore(reducer);

  3.
    <Provider store={store}>
      <App/>
    </Provider>

  4.哪个组件需要 *使用数据*
    就在哪个组件中引入 react-redux 中的 connect
      import {connect} from 'react-redux'
      import { bindActionCreators} from 'redux'
    在导出的地方 把组件用 connect 包一下        
    connect((state)=>state)(组件的名字)
      比如:
        export default connect((state)=>state,(dispatch)=>{
          return bindActionCreators(actioncreators,dispatch);
        })(组件的名名字);
 
    state 就是 reducer 下的 state 状态

    那么做之后,就可以通过 this.props.xx 去获取状态值

    this.props.dispatch 去发起 action




注意点:
***如果使用了 connect 路由跳转会失效,此时要使用withRouter解决
  比如:
    export default withRouter(connect(state=>state,(dispatch)=>bindActionCreators(actioncreators,dispatch))(App));
 
***数据变化了,视图却没有更新,应该注意state是否需要深克隆 可以用JSON.parse(JSON.stringify( arr ))

// export defore connect((state)=>{

  /* 

    !!! 此处一定要返回一个对象

    可以选择这个组件能用的数据。默认全部数据都返回

  */ 

})(App)


 
reducer中state可以是简单类型也可以是复合类型

如果是简单类型是可以直接更改state的
如果是复合类型的,每一次修改必须赋值一个新的地址,方便管理
  state = {a:5}
  state = {a:6}
  [{a:5},{a:6}]
 
 
redux:
  createStore(reducer,initialstate,middleware)
    initialstate:初始值
    middleeware:中间件的接口
    也可以这么写:
      createStore( reducer,middleware)
    用的比较多的 thunk (为了异步操作,用 applymiddleware(thunk) ),thunk 是中间件。?????????????????????? 

  combineReducers({})
    可以放入多个 reducer

  bindActionCreators(actioncreats,dispatch)
    返回一个对象,可以把actions直接挂到this.props下

  actioncreators
    发起action的小函数
    const ADD = 'ADD'; 为了让action是唯一,所以用变量。
    function add(){
      return {
        type:ADD
      }
    }
  
 
react-redux
  Provider 挂在顶层,并且挂一个属性叫store={store}
  connect 哪个组件需要状态管理器中的数据,就用connect包裹
  返回新的组件

  let mapStateProp = (state,ownProps)=>{
    state状态管理器中的所有数据,
    也可以返回一个当前组件需要的数据
    return state; //必须返回对象
  }

  let mapDispatchProp = (dispatch,ownProps) => {
    return bindActionCreators(actionCreators,dispatch)
  }

  ownProps:只要接收到的新的父级传进来的数据,就会在运行一次此函数

  connect(mapStateProp,mapDispatchProp)(App)


英文储备: 

  redux  “统一”的状态管理,不能直接更改状态

  state  状态

  type  类型

  createStore   创建文件
  getState  获取状态
  initState  初始状态
  reducer  管理员,负责如何更改状态

  dispatch  派发  (参数是  action  动作,规定action是一个对象,这个对象必须有一个type属性 { type:"自定义" })

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<body>
    <div class="title"></div>
    <div class="content"></div>
    <script src="./试试.js"></script>
</body>
</html>
DOM
 1 // redux “统一”的状态管理,不能直接更改状态
 2 function createStore(reducer) { //将状态放到一个盒子里,别人就改不了了。
 3     let state;//状态
 4     function dispatch (action){  //派发 参数是action 动作,规定action是一个对象,这个对象必须有个type属性{type:'自定义'} 
 5         state = reducer(state,action);//调用写好的方法,这个方法会返回一个新的状态,覆盖掉老状态
 6     };
 7     dispatch({});
 8     let getState = () =>JSON.parse(JSON.stringify(state)) //获取状态的方法
 9     return {
10         getState,
11         dispatch
12     }
13 }
14 
15 
16 let initState = {  //初始状态
17     titleState:{color:'red',text:'标题'},
18     contentState:{color:'green',text:'内容'},
19 }
20 
21 
22 let store = createStore(reducer);//创建容器时需要传递一个管理员
23 
24 
25 function reducer(state=initState,action){  //管理员,负责如何更改状态
26     switch (action.type){   //更改状态  要用一个新的状态覆盖掉
27         case 'CHANGE_TITLE_TEXT':
28             return{...state,titleState:{...state.titleState,text:action.text}};
29         case 'CHANGE_CONTENT_COLOR':
30             return{...state,contentState:{...state.contentState,color:action.color}};
31     }
32     return state;
33 }
34 
35 
36 //宏  定义一个常量
37 const CHANGE_TITLE_TEXT = 'change_title_text'; 
38 const CHANGE_CONTENT_COLOR = 'change_content_color';
39 
40 
41 function renderTitile(){
42     let title = document.querySelector('.title');
43     title.innerHTML = store.getState().titleState.text;
44     title.style.color = store.getState().titleState.color
45 }
46 function renderContent(){
47     let content = document.querySelector('.content');
48     content.innerHTML = store.getState().contentState.text;
49     content.style.color = store.getState().contentState.color
50 }
51 function renderApp(){
52     renderTitile()
53     renderContent()
54 }
55 renderApp()
56 setTimeout(()=>{
57     store.dispatch({type:'CHANGE_TITLE_TEXT',text:'长标题'}) //除了type的属性,其它的都叫payload 载荷
58     store.dispatch({type:'CHANGE_CONTENT_COLOR',color:'blue'})
59     renderApp();//每次派发完都需要render
60 },3000)
JS,Redux实现原理
 
原文地址:https://www.cnblogs.com/MrZhujl/p/10300935.html