美文网首页
Reducer Hook

Reducer Hook

作者: percykuang | 来源:发表于2020-05-24 10:20 被阅读0次

    Reducer Hook

    Flux:Facebook出品的一个数据流框架

    1. 规定了数据是单向流动的
    2. 数据存储在数据仓库中(目前,可认为state就是一个存储数据的仓库)
    3. action是改变数据的唯一原因(本质上就是一个对象,action有两个属性)
      1. type:字符串,动作的类型
      2. payload:任意类型,动作发生后的附加信息
    4. 具体改变数据的是个函数,该函数叫做reducer
      1. 该函数接收两个参数
        1. state:表示当前数据仓库中的数据
        2. action:描述了如何去改变数据,以及改变数据的一些附加信息
      2. 该函数必须有一个返回结果,用于表示数据仓库变化之后的数据
        1. Flux要求,对象是不可变的。如果返回对象,必须创建新的对象
    5. 如果要触发reducer,不可直接调用,而是应该调用一个辅助函数dispatch
      1. 该函数仅接受一个参数:action
      2. 该函数会间接去调用reducer,以达到改变数据的目的

    自己手写这个数据流:

    import React, { useState } from 'react'
    
    function reducer(state, action) {
      switch (action.type) {
        case 'increase':
          return state + 1
        case 'decrease':
          return state - 1
        default:
          return state
      }
    }
    
    export default function HookCounter() {
    
      const [count, setCount] = useState(0)
    
      function dispatch(action) {
        const newCount = reducer(count, action)
        console.log(`日志:n的值  ${count} => ${newCount}`)
        setCount(newCount)
      }
    
      return (
        <div>
          <button onClick={() => dispatch({type: 'increase'})}>+</button>
          <span>{count}</span>
          <button onClick={() => dispatch({type: 'decrease'})}>-</button>
        </div>
      )
    }
    

    使用自定义Hook优化:

    import React, { useState } from 'react'
    
    function reducer(state, action) {
      switch (action.type) {
        case 'increase':
          return state + 1
        case 'decrease':
          return state - 1
        default:
          return state
      }
    }
    
    function useMyReducer() {
      const [count, setCount] = useState(0)
      function dispatch(action) {
        const newCount = reducer(count, action)
        console.log(`日志:n的值  ${count} => ${newCount}`)
        setCount(newCount)
      }
      return [count, dispatch]
    }
    
    export default function HookCounter() {
    
      const [count, dispatch] = useMyReducer()
    
      return (
        <div>
          <button onClick={() => dispatch({type: 'increase'})}>+</button>
          <span>{count}</span>
          <button onClick={() => dispatch({type: 'decrease'})}>-</button>
        </div>
      )
    }
    

    通用化自定义reducer:

    import React, { useState } from 'react'
    
    function reducer(state, action) {
      switch (action.type) {
        case 'increase':
          return state + 1
        case 'decrease':
          return state - 1
        default:
          return state
      }
    }
    
    /**
     * 通用的useMyReducer函数
     * @param {function} reducer reducer函数,标准格式的
     * @param {any} initialState 初始状态
     */
    function useMyReducer(reducer, initialState) {
      const [state, setState] = useState(initialState)
    
      function dispatch(action) {
        const newState = reducer(state, action)
        console.log(`日志:  ${state} => ${newState}`)
        setState(newState)
      }
      return [state, dispatch]
    }
    
    export default function HookCounter() {
    
      const [count, dispatch] = useMyReducer(reducer, 0)
    
      return (
        <div>
          <button onClick={() => dispatch({type: 'increase'})}>+</button>
          <span>{count}</span>
          <button onClick={() => dispatch({type: 'decrease'})}>-</button>
        </div>
      )
    }
    

    使用Reducer Hook

    import React, { useState, useReducer } from 'react'
    
    function reducer(state, action) {
      switch (action.type) {
        case 'increase':
          return state + 1
        case 'decrease':
          return state - 1
        default:
          return state
      }
    }
    
    export default function HookCounter() {
    
      // useReducer 第三个参数是可选的函数 函数返回数用来替代第二个参数(初始状态)
      const [count, dispatch] = useReducer(reducer, 7, (secondParam) => {
        // 传过来的参数是 第二个参数 -> 7
        console.log(secondParam)
        // 现在初始值不是7 而是100了
        return 100
      })
      
      // 第三个参数通常没啥用 它的本意是通过对第二个参数进行一大堆运算 再重新得到一个初始值
    
      return (
        <div>
          <button onClick={() => dispatch({type: 'increase'})}>+</button>
          <span>{count}</span>
          <button onClick={() => dispatch({type: 'decrease'})}>-</button>
        </div>
      )
    }
    

    相关文章

      网友评论

          本文标题:Reducer Hook

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