• reactjs —— useState useReducer :页面元素设置 & 元素之间的联动


    原文:

    https://www.react.express/hooks/usereducer

    useReducer

    The useReducer hook is similar to useState, but gives us a more structured approach for updating complex values.

    We typically use useReducer when our state has multiple sub-values, e.g. an object containing keys that we want to update independently.

    API

    The useReducer hook requires 2 arguments, and has an optional 3rd argument:

    • reducer - a pure function that takes a state and an action, and returns a new state value based on the action
    • initialState - any initial state value, just like useState
    • initializer (optional) - this is uncommon, but we'll briefly introduce it later.

    The useReducer hook returns the current state, and a dispatch function to update the state.

    Dispatch

    The dispatch function takes an action, and calls the reducer to update the state.

    In the example below, the initial state is {color: 'black', pet: 'cat'}. When we select dog from the dropdown, dispatch is called with {type: types.PET, value: 'dog'} as its argument. This argument gets passed to the reducer as action. Then the reducer follows the switch case logic case types.PET and returns the new state: the current color and the pet contained in the action, {color: 'black', pet: 'dog'}

    We typically use constants to identify the type for the switch case (e.g. PET or COLOR) to avoid typos and to make it easier to change in the future if needed.

    import React, { useReducer } from 'react'
    import { render } from 'react-dom'
    
    const types = {
      PET: 'PET',
      COLOR: 'COLOR',
    }
    
    const reducer = (state, action) => {
      switch (action.type) {
        case types.PET:
          return { ...state, pet: action.value }
        case types.COLOR:
          return { ...state, color: action.value }
      }
    }
    
    const initialState = {
      color: 'black',
      pet: 'cat',
    }
    
    export default function App() {
      const [state, dispatch] = useReducer(reducer, initialState)
    
      return (
        <div>
          <label>Choose a color and a pet: </label>
          <br />
          <select
            value={state.color}
            onChange={event => {
              dispatch({ type: types.COLOR, value: event.target.value })
            }}
          >
            <option value="black">Black</option>
            <option value="pink">Pink</option>
            <option value="blue">Blue</option>
          </select>
          <select
            value={state.pet}
            onChange={event => {
              dispatch({ type: types.PET, value: event.target.value })
            }}
          >
            <option value="cat">Cat</option>
            <option value="dog">Dog</option>
            <option value="mouse">Mouse</option>
          </select>
          <br />
          <br />
          You chose a {state.color} {state.pet}
        </div>
      )
    }
    
    render(<App />, document.querySelector('#app'))
    

      

    useState vs. useReducer

    These hooks are conceptually similar: they both store state variables. So, when should we use one or the other?

    Consider the example above. If we were to use useState in this scenario, what would it look like? One option would be two state variables:

     

    const [color, setColor] = useState('black')
    const [pet, setPet] = useState('cat')
    
    // ...
    
    setColor('pink')
    setPet('dog')
    

      

    This option works well when our state variables are independent: e.g. changing the pet will never also change the color, or vice versa. However, when we have multiple state variables that depend on one another, it can become challenging to keep everything in sync.

    Another option would be a single object that we update manually:

    const [state, setState] = useState({ color: 'black', pet: 'cat' })
    
    // ...
    
    setState({ ...state, color: 'pink' })
    setState({ ...state, pet: 'dog' })
    

      

    This option lets us update all state variables at once, making it easier to keep things in sync. This option works well when our state object is small, but as soon as it becomes larger, our code for updating the state will start taking up a lot of lines, making it harder to follow the logic of our component.

    The useReducer hook essentially takes this second approach (a single state object), and provides a more structured API. We can then move our state-handling code outside of our component, so our component logic is clearer and our state logic can be tested independently. Additionally, if we want to allow children components to update the state, we can pass the dispatch function down into children as a prop, rather than creating a separate callback prop for every possible change a child might want to make.

    In summary:

    • Use useState for "simple" state, like JavaScript primitive values
    • Use useReducer when there are different sub-values that depend on one another

    The third argument: Initializer

    We mentioned this uncommon option briefly above: useReducer allows us to initialize state lazily with an initializer function. This is useful when creating the initial state is computationally expensive.

    const computeMeaningOfLife = initialArg => {
    // Do some computationally expensive work...
    return { meaningOfLife: initialArg }
    }
    
    const [state, dispatch] = useReducer(reducer, 42, computeMeaningOfLife)
    
    console.log(state)
    // => { meaningOfLife: 42 }
    

      

  • 相关阅读:
    react入门教程 |菜鸟教程
    React 组件构造方法: ES5 (createClass) 还是 ES6 (class)?
    代码设置LinearLayout的高度
    android调用webservice发送header身份验证不成功
    GridView中item获得焦点放大缩小
    关于url从服务器上获取图片资源
    Android中删除照片操作
    android采用Ksoap2访问webservice,AndroidHttpTransport call方法异常
    创建新的Android项目,Eclipse自动创建的appcompat内容
    Windroy、Windroye、Bluestacks运行Android实现原理
  • 原文地址:https://www.cnblogs.com/panpanwelcome/p/15267533.html
Copyright © 2020-2023  润新知