07/redux

 <pre>
    當有以下須要能夠考慮使用redux:
      當組件的狀態,須要共享
      某個狀態須要在任何地方均可以拿到
      一個組件須要改變全局狀態
      一個組件須要改變另外一個組件的狀態

      vue中是   
                   store(state,mutation,action)
          |----------------------- |     
          |  action --->mutation   |
          |-- ↑-------        ↑    |    
           dispatch  |        |    |
              |      |        |    |
              |      |        ↓    |
      component<-----|-----state   |                                           
                     |--------------            | 



             state能夠由組件直接獲取獲得 
             組件diapatch  action 或commit mutation    來實現數據state的修改       
  

react沒有vuex那麼清晰,在store裏定義state(狀態),action等  主要定義reducer和action
react中reduce至關於mutation,store不須要定義聲明,有reducer自動完成
組件經過store.getState()得到狀態
組件怎麼改狀態?經過容器dispatch去改-->也就是store.dispatch(Action)   這個Action至關於從新觸發掉了reducer  從新產生State,State一變化就觸發組件變化。流向和vuex是同樣的
component--->Action--->reducer--->state--->component     可是不把store,reducer,action所有叫store   這每個東西都是普通的

  </pre>

02vue

 <script type="text/babel">
    //count數據  用redux存
    //VUEX的使用:1)建立容器 定義state,action,mutation 2)容器掛載到Vue實例上  3)組件獲取狀態或修改狀態
    //Redux:
    //reducer:用於產生state的函數  定義reducer才能知道count是什麼數據
   //                        reducer根據對應的action產生state
    //action 是個普通對象,用於記錄用戶的行爲  裏面屬性其實能夠隨便定,但規範上通常是給{type:''}
    // store  根據reducer函數建立

//六步驟
    //1.定義Reducer:是個函數  怎麼定義隨意 名字隨便取,可是裏面參數的含義是固定的
    //第一個參數,上一次的狀態  state是由reducer建立的,因此一次都沒調用的時候可能沒有定義,能夠給個初始化  
    //第二個參數是用戶提交的action對象
    //返回值爲新狀態
    function myCount(state=0,action){
      //這個state其實就表明count
      //reducer就是根據action產生state
      //傳遞給個人action究竟是個什麼行爲,全部要根據action.type判斷
      //reducer最終返回的是一個新狀態
      switch(action.type){
        case 'ADD':
          return state+1
        case 'SUB':
          return state-1
          //必定要定義默認狀況
        default:return state   //返回舊狀態
      }
    }


    //2.reduce作好後建立容器
    //  建立store:用Redux.createStore     這個方法接受一個參數,就收Reducer做參數  根據這個Reducer就能產生容器(store)
    const store=Redux.createStore(myCount)

    //3.有時候可寫可不寫,簡單的話能夠不寫  建立Action函數,Action Creator  是個函數,做用是建立action(一個對象)  return一個對象
      //能夠由參數也能夠沒有
    function setCount(type){
      //返回Action
      return{
        type
      }
    }

    //4 建立組件   獲取狀態   修改狀態
    class App extends React.Component{
      add=()=>{
        //讓狀態+1   reducer已將幫你作了  只要去執行一遍就行
        //只要去調用reducer  這時候用store.dispatch  store是全局變量
        //dispatch參數爲action
        //addCount就是幫咱們生成action對象的   因此這裏得dispatch的參數就位action函數  不然簡單的話能夠不用這個addCount函數  直接store.dispatch({type:"ADD"})
        store.dispatch(setCount('ADD'))
        //一dispatch  立刻就會去調用reducer函數(也就是myCount),action傳給myCount的第二個參數  這時候state就變了  state+1了
        //但這時候是不會更新視圖的
      }
      sub=()=>{
        //讓狀態-1
        store.dispatch(setCount('SUB'))
      }

      render(){
        return(
          <div>
            {/*獲取狀態 store.getState()   拿到了state(就是count數字)*/}
            <p>{store.getState()}</p>
            <button onClick={this.add}>+</button>  
            <button onClick={this.sub}>-</button>  
          </div>
        )
      }
    }
    //5.渲染組件
    ReactDOM.render(<App/>,document.getElementById('root'))

    //6.監聽狀態變化,從新渲染頁面  store.subscribe會自動監聽state的更新
    store.subscribe(function(){
      ReactDOM.render(<App/>,document.getElementById('root'))
    })

    
    </script>

03react

<div id='root'></div>
    <script src="./react.js"></script>
    <script src="./react-dom.js"></script>
    <script src="./react-router-dom.js"></script>
    <script src="./redux.js"></script>
    <script src="./babel.min.js"></script>
    <script type="text/babel">
   
      //需求:共享數據count,行爲有:加某個值,減某個值
      //1.定義Reducer:Reducer是函數,用於根據就狀態和Action產生新狀態

      //myCount這個函數由你去定義但不是否是由你直接去調用  而是由你去dispatch的時候由內部的Redux經過store自動的去調用
      //因此裏面的形參不能換順序,調用者根據規則去調用的,因此要按規則去定義,第一個就要定義state,第二個是action
      //redux的action個vuex不一樣  vuex的action是方法(函數),  redux的是對象  且有不成文的規則,要有一個type屬性 不叫type也能夠  不過都用type {type}
      //state=0這個初始值能夠在建立recuder的時候在形參裏設置,也能夠在第二步建立容器的時候指定
      function myCount(state=0,action){
        debugger
        switch (action.type) { //action:{type:表示行爲名稱,payload:行爲所攜帶的數據(推薦用payload)}
          case 'ADD':
            return  state+action.payload
          case 'SUB':
            return
          default: return state-action.payload
          
        }
      }

      //2.建立容器 第一個參數就是recuder,第二個參數就是狀態初始值(可選,但這裏不寫那麼reducer(myCount)就要寫,不然會顯示NAN)
      const store = Redux.createStore(myCount,0)

      //3.定義建立Action的方法,Action Creator
      function myActionCreator(type,payload=1) {
        return {
          type,
          payload
        }
      }

      //4.設計組件
      class App extends React.Component{
        render(){
          console.log(store.getState())
          debugger
          return(
            <div>
              <p>{store.getState()}</p>
              <button>+</button>   
              <button>-</button>   
            </div>
          )
        }
      }
      function myRender(){
        ReactDOM.render(<App/>,document.getElementById('root'))
      }
      myRender()

      //這裏只是講的redux  redux自己是不能自動更新組件的(state變化的話)   後面有一個react-redux  這個作的是自動監聽state變化  會直接引發視圖變化  只用redux纔有第五步

      //5.監聽狀態改變 store.subscribe(myCount)是有返回值的  執行這個返回值就會解除監聽
      var unSubScribe=store.subscribe(myCount)

      // setTimeout(()=>unSubScribe(),20000)//解除監聽



   
    </script>

04vuex

  <style>
  .del{
    text-decoration: line-through
  }
  </style>
</head>
<body>
  <div id='root'></div>
    <script src="./react.js"></script>
    <script src="./react-dom.js"></script>
    <script src="./react-router-dom.js"></script>
    <script src="./redux.js"></script>
    <script src="./babel.min.js"></script>
    <script type="text/babel">
    //1.設置reducer
      function todoList(state=[],action){
        switch (action.type) {
          case 'ADD_LIST':
            
            return [
              ...state,
              action.payload
            ]
          case 'DELETE_ITEM':
            return [
              ...state.slice(0,action.index),
              ...state.slice(action.index+1)
            ]
          case 'TOGO_TODO':
            return [
            ...state.slice(0,action.index),
              Object.assign(state[action.index],{isCompleted:!state[action.index].isCompleted}),
              ...state.slice(action.index+1)
            ]
          case 'CLEAR_LIST':
            return []
              
            
          default: return state
            
        }
      }

      //多個reducer能夠合併

      const totalCount=function(state=0,action){
        switch(action.type) {
          case 'CHANGE_TOTAL': //修改總數量
            return action.payload
          case 'ADD_TOTAL':
            return state+1
          case 'SUB_TOTAL':
            return state-1
          default: return state
        }
      }

    //combineReducers的參數,爲一個對象,該對象key是state中的屬性,value是產生對應state的reducer函數
      const allReducer=Redux.combineReducers({
        todoList,
        totalCount
      })

    //2.建立容器
    const store=Redux.createStore(allReducer)
    
    //3.設置action Creator
    function addlist(payload){
      return {
        type:'ADD_LIST',
        payload
      }
    }
    function deleteItem(index){
      return {
        type:'DELETE_ITEM',
        index
      }
    }
    function check(index){
      return {
        type:'TOGO_TODO',
        index
      }
    }


    //定義totalChange的Action Creator
    function changeTotalCount(){
      return 
    }
    //4 建立UI

    class App extends React.Component{
      render(){
        return(<div>
          標籤內容
          <TodoList/>
          <AddItem/>
          </div>)
      }
    }

  class TodoList extends React.Component{

    del=(index)=>{
      store.dispatch(deleteItem(index))
    }
    check=(index)=>{
      store.dispatch(check(index))
    }
    render(){
      return(<ul>
        {store.getState().todoList.map((val,index)=>{
          return(<li>
            <input type="checkbox" checked={val.isCompleted} onChange={e=>this.check(index)} />
            <span  className={val.isCompleted?'del':''}>{val.content}</span>
            <button onClick={e=>this.del(index)}>刪除</button>
            </li>)
        })
        
        }
        </ul>)
    }
  }

  class AddItem extends React.Component{
    
    add=()=>{
        this.inputItem.value!==''?store.dispatch(addlist({content:this.inputItem.value,isCompleted:false})):alert('請輸入事件')
      }
    render(){
      return(<div>
          <input ref={(el)=>this.inputItem=el}/>
          <button onClick={this.add}>保存</button>
        
        </div>)
    }
  }


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

05redux

 <div id='root'></div>
    <script src="./react.js"></script>
    <script src="./react-dom.js"></script>
    <script src="./react-router-dom.js"></script>
    <script src="./redux.js"></script>
    <script src="./babel.min.js"></script>
    <script type="text/babel">
  
    class App extends React.Component{
      constructor(props){
        super(props)
      }
      add=()=>{
        //讓狀態+1   reducer已將幫你作了  只要去執行一遍就行
        //只要去調用reducer  這時候用store.dispatch  store是全局變量
        //dispatch參數爲action
        //addCount就是幫咱們生成action對象的   因此這裏得dispatch的參數就位action函數  不然簡單的話能夠不用這個addCount函數  直接store.dispatch({type:"ADD"})
        // store.dispatch(setCount('ADD'))
        //一dispatch  立刻就會去調用reducer函數(也就是myCount),action傳給myCount的第二個參數  這時候state就變了  state+1了
        //但這時候是不會更新視圖的
      }
      sub=()=>{
        //讓狀態-1
        store.dispatch(setCount('SUB'))
      }

      render(){
        return(
          <div>
     
          </div>
        )
      }
    }
    const a1=new App()
    debugger
    //5.渲染組件
    ReactDOM.render(<App/>,document.getElementById('root'))

    //6.監聽狀態變化,從新渲染頁面  store.subscribe會自動監聽state的更新
    store.subscribe(function(){
      ReactDOM.render(<App/>,document.getElementById('root'))
    })

    
    </script>

06babel

 <div id='root'></div>
    <script src="./react.js"></script>
    <script src="./react-dom.js"></script>
    <script src="./react-router-dom.js"></script>
    <script src="./redux.js"></script>
    <script src="./babel.min.js"></script>
    <script type="text/babel">
    //1.定義reducer  是個函數
    function reducer1(state = 0 ,action){
      switch (action.type){
        default:return state ;break;
      }
    }
    //2.reducer作好後建立容器
    const store = Redux.createStore(reducer1)

    //3.建立action函數,做用是return一個對象
    function action(type){
      return type
    }

    //創個組件

    class App extends React.Component{
      render(){
        return <div>11</div>
      }
    }
    ReactDOM.render(<App/>,document.getElementById('root'))

    </script>
本站公眾號
   歡迎關注本站公眾號,獲取更多信息