zoukankan      html  css  js  c++  java
  • 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 }
    

      

  • 相关阅读:
    分布式缓存技术PK:选择Redis还是Memcached?
    Redis实战:如何构建类微博的亿级社交平台
    Redis内存使用优化与存储
    微信小程序 Image 图片实现宽度100%,高度自适应
    小程序跳转、请求、带参数请求小例子
    微信小程序 全局变量
    免费ftp服务器FileZilla Server配置
    分享一次在Windows Server2012 R2中安装SQL Server2008
    C# litJson 使用方法
    HttpHandler和ashx要实现IRequiresSessionState接口才能访问Session信息(转载)
  • 原文地址:https://www.cnblogs.com/panpanwelcome/p/15267533.html
Copyright © 2011-2022 走看看