美文网首页
自己实现Redux

自己实现Redux

作者: 解勾股 | 来源:发表于2019-06-25 23:59 被阅读0次

    自己实现Redux

    不使用react,直接使用原生的html/js来写一个简易的的redux

    基本的状态管理及数据渲染

    <!DOCTYPE html>
    <html lang="en">
    <head>
      <meta charset="UTF-8">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <meta http-equiv="X-UA-Compatible" content="ie=edge">
      <title>Redux principle 01</title>
    </head>
    <body>
      <h1>redux principle</h1>
      <div class="counter">
        <span class="btn" onclick="dispatch({type: 'COUNT_DECREMENT', number: 10})">-</span>
        <span class="count" id="count"></span>
        <span class="btn" id="add" onclick="dispatch({type: 'COUNT_INCREMENT', number: 10})">+</span>
      </div>
      <script>
        // 定义一个计数器的状态
        const countState = {
          count: 10
        }
    
        // 定一个方法叫changeState,用于处理state的数据,每次都返回一个新的状态
        const changeState = (action) => {
          switch(action.type) {
            // 处理减
            case 'COUNT_DECREMENT':
              countState.count -= action.number
              break;
            // 处理加        
            case 'COUNT_INCREMENT':
              countState.count += action.number
              break;
            default:
              break;
          }
        }
    
        // 定义一个方法用于渲染计数器的dom
        const renderCount = (state) => {
          const countDom = document.querySelector('#count')
          countDom.innerHTML = state.count
        }
      
        // 首次渲染数据
        renderCount(countState)
    
        // 定义一个dispatch的方法,接收到动作之后,自动调用
        const dispatch = (action) => {
          changeState(action)
          renderCount(countState)
        }
    
      </script>
    </body>
    </html>
    

    创建createStore方法

    <!DOCTYPE html>
    <html lang="en">
    <head>
      <meta charset="UTF-8">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <meta http-equiv="X-UA-Compatible" content="ie=edge">
      <title>Redux principle 02</title>
    </head>
    <body>
      <h1>redux principle</h1>
      <div class="counter">
        <span class="btn" onclick="store.dispatch({type: 'COUNT_DECREMENT', number: 10})">-</span>
        <span class="count" id="count"></span>
        <span class="btn" id="add" onclick="store.dispatch({type: 'COUNT_INCREMENT', number: 10})">+</span>
      </div>
      <script>
        // 定义一个方法,用于集中管理state和dispatch
        const createStore = (state, changeState) => {
          // getState用于获取状态
          const getState = () => state
          
          // 定义一个监听器,用于管理一些方法
          const listeners = []
          const subscribe = (listener) => listeners.push(listener)
    
           // 定义一个dispatch方法,让每次有action传入的时候返回render执行之后的结果
          const dispatch = (action) => {
            // 调用changeState来处理数据
            changeState(state, action)
            // 让监听器里的所以方法运行
            listeners.forEach(listener => listener())
          }
          return {
            getState,
            dispatch,
            subscribe
          }
        }
        // 定义一个计数器的状态
        const countState = {
          count: 10
        }
        // 定一个方法叫changeState,用于处理state的数据,每次都返回一个新的状态
        const changeState = (state, action) => {
          switch(action.type) {
            // 处理减
            case 'COUNT_DECREMENT':
              state.count -= action.number
              break;
            // 处理加        
            case 'COUNT_INCREMENT':
              state.count += action.number
              break;
            default:
              break;
          }
        }
    
        // 创建一个store
        const store = createStore(countState, changeState)
        // 定义一个方法用于渲染计数器的dom
        const renderCount = () => {
          const countDom = document.querySelector('#count')
          countDom.innerHTML = store.getState().count
        }
        // 初次渲染数据
        renderCount()
        // 监听,只要有dispatch,这个方法就会自动运行
        store.subscribe(renderCount)
      </script>
    </body>
    </html>
    

    让changeState方法变为一个纯函数

    <!DOCTYPE html>
    <html lang="en">
    <head>
      <meta charset="UTF-8">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <meta http-equiv="X-UA-Compatible" content="ie=edge">
      <title>Redux principle 03</title>
    </head>
    <body>
      <h1>redux principle</h1>
      <div class="counter">
        <span class="btn" onclick="store.dispatch({type: 'COUNT_DECREMENT', number: 10})">-</span>
        <span class="count" id="count"></span>
        <span class="btn" id="add" onclick="store.dispatch({type: 'COUNT_INCREMENT', number: 10})">+</span>
      </div>
      <script>
        // 定义一个方法,用于集中管理state和dispatch
        const createStore = (state, changeState) => {
          // getState用于获取状态
          const getState = () => state
          
          // 定义一个监听器,用于管理一些方法
          const listeners = []
          const subscribe = (listener) => listeners.push(listener)
    
          // 定义一个dispatch方法,让每次有action传入的时候返回render执行之后的结果
          const dispatch = (action) => {
            // 调用changeState来处理数据
            state = changeState(state, action)
            // 让监听器里的所有方法运行
            listeners.forEach(listener => listener())
          }
          return {
            getState,
            dispatch,
            subscribe
          }
        }
        // 定义一个计数器的状态
        const countState = {
          count: 10
        }
        // 定一个方法叫changeState,用于处理state的数据,每次都返回一个新的状态
        const changeState = (state, action) => {
          switch(action.type) {
            // 处理减
            case 'COUNT_DECREMENT':
              return {
                ...state,
                count: state.count - action.number
              }
            // 处理加        
            case 'COUNT_INCREMENT':
              return {
                ...state,
                count: state.count + action.number
              }
            default:
              return state
          }
        }
    
        // 创建一个store
        const store = createStore(countState, changeState)
        // 定义一个方法用于渲染计数器的dom
        const renderCount = () => {
          const countDom = document.querySelector('#count')
          countDom.innerHTML = store.getState().count
        }
        // 初次渲染数据
        renderCount()
        // 监听,只要有dispatch,这个方法就会自动运行
        store.subscribe(renderCount)
      </script>
    </body>
    </html>
    

    合并state和changeState(最终版)

    <!DOCTYPE html>
    <html lang="en">
    <head>
      <meta charset="UTF-8">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <meta http-equiv="X-UA-Compatible" content="ie=edge">
      <title>Redux principle 04</title>
    </head>
    <body>
      <h1>redux principle</h1>
      <div class="counter">
        <span class="btn" onclick="store.dispatch({type: 'COUNT_DECREMENT', number: 10})">-</span>
        <span class="count" id="count"></span>
        <span class="btn" id="add" onclick="store.dispatch({type: 'COUNT_INCREMENT', number: 10})">+</span>
      </div>
      <script>
        // 定义一个方法,用于集中管理state和dispatch, changeState改名了,专业的叫法是reducer
        const createStore = (reducer) => {
          // 定义一个初始的state
          let state = null
          // getState用于获取状态
          const getState = () => state
          
          // 定义一个监听器,用于管理一些方法
          const listeners = []
          const subscribe = (listener) => listeners.push(listener)
    
          // 定义一个dispatch方法,让每次有action传入的时候返回reducer执行之后的结果
          const dispatch = (action) => {
            // 调用reducer来处理数据
            state = reducer(state, action)
            // 让监听器里的所有方法运行
            listeners.forEach(listener => listener())
          }
          //  初始化state
          dispatch({})
          return {
            getState,
            dispatch,
            subscribe
          }
        }
        // 定义一个计数器的状态
        const countState = {
          count: 10
        }
        // 定一个方法叫changeState,用于处理state的数据,每次都返回一个新的状态
        const changeState = (state, action) => {
          // 如果state是null, 就返回countState
          if (!state) return countState
          switch(action.type) {
            // 处理减
            case 'COUNT_DECREMENT':
              return {
                ...state,
                count: state.count - action.number
              }
            // 处理加        
            case 'COUNT_INCREMENT':
              return {
                ...state,
                count: state.count + action.number
              }
            default:
              return state
          }
        }
    
        // 创建一个store
        const store = createStore(changeState)
        // 定义一个方法用于渲染计数器的dom
        const renderCount = () => {
          const countDom = document.querySelector('#count')
          countDom.innerHTML = store.getState().count
        }
        // 初次渲染数据
        renderCount()
        // 监听,只要有dispatch,renderCount就会自动运行
        store.subscribe(renderCount)
      </script>
    </body>
    </html>
    

    相关文章

      网友评论

          本文标题:自己实现Redux

          本文链接:https://www.haomeiwen.com/subject/vsgfcctx.html