zoukankan      html  css  js  c++  java
  • 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实现原理
     
  • 相关阅读:
    T4设计时模板调试
    MVC开发T4代码生成之一文本模板基础
    经典选项卡
    IE 调试工具 Utilu IE Collection:IE5.5、6.0、7.0, 8.0…各版本浏览器兼容性测试工具
    滚动读行!
    自定义标签的用法、支持IE6
    jQuery 参数传递例子
    IMG在IE6下不能HOVER的解决办法!
    点击渐变弹出层
    操作滚动条滚动到指定位置
  • 原文地址:https://www.cnblogs.com/MrZhujl/p/10300935.html
Copyright © 2011-2022 走看看