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>

02

 <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>

03

<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>

04

  <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>

05

 <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>

06

 <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>

猜你喜欢

转载自www.cnblogs.com/lucy-xyy/p/11654171.html
07