zoukankan      html  css  js  c++  java
  • useState使用和原理

    Hooks 是 React 16 中的特性,解决函数组件想使用类组件的一些特性。

    关于更多 Hooks 介绍,请参考 React 官网[1]

    useState
    之前是在类组件中使用状态通过 state 定义,大概代码是这样的。

    import React from 'react';    
    class Counter extends React.Component {    
      state = {    
        number: 0    
      }    
      handleClick = () => {    
        this.setState({    
          number: this.state.number + 1    
        })    
      }    
      render() {    
        return (    
          <>    
            <p>{this.state.number}</p>    
            <button    
              onClick={ this.handleClick }>    
              改数字    
            </button>    
          </>    
        );    
      }    
    }    
    function render() {    
      ReactDOM.render(<Counter />, document.getElementById('root'));    
    }    
    render()


    但是函数组件没有实例,也没有状态。函数组件使用状态需要使用 useState 钩子。

    关于 useState 的用法是,需要传入一个参数作为状态的初始值,当函数执行后会返回两个值,一个是当前状态的属性,一个是修改状态的方法。

    我们通过一个计数器的例子,当点击按钮表示状态加1。

    import React, {useState} from 'react';    
    function Counter() {    
      const [    
        number,    
        setNumber    
      ] = useState(0)    
      return (    
        <>    
          <p>{number}</p>    
          <button    
            onClick={    
              () => setNumber(number + 1)    
            }    
          >    
            改数字    
          </button>    
        </>    
      )    
    }    
    function render() {    
      ReactDOM.render(<Counter />, document.getElementById('root'));    
    }    
    render()


    现在我们已经掌握了它的用法,那么我们开始分析它的原理。

    原理
    我们需要写一个 useState 方法,会返回当前状态的属性和设置状态的方法,每当状态改变之后,方法中会调用刷新视图的 render 方法。

    let memoizedState;    
    function useState (initialState) {    
      memoizedState = memoizedState || initialState    
      function setState (newState) {    
        memoizedState = newState    
        render()    
      }    
      return [memoizedState, setState]    
    }


    再次尝试之前的代码,依然可以正常使用,但是当多个 useState 存在的时候就有问题了,只能变一个状态了。

    function Counter() {    
      const [    
        number,    
        setNumber    
      ] = useState(0)    
      const [    
        title,    
        setTitle    
      ] = useState('随机标题')    
      return (    
        <>    
          <h1>{title}</h1>    
          <p>{number}</p>    
          <button    
            onClick={    
              () => setNumber(number + 1)    
            }    
          >    
            改数字    
          </button>    
          <button    
            onClick={    
              () => setTitle(`随机标题${Math.random()}`)    
            }    
          >    
            改标题    
          </button>    
        </>    
      )    
    }

    现在我们需要优化我们的 Hooks ,解决多个 useState 同时使用的问题,当多个状态存在的时候,我们需要使用数组保存状态。

    let memoizedStates = []    
    let index = 0    
    function useState (initialState) {    
      memoizedStates[index] = memoizedStates[index] || initialState    
      let currentIndex = index    
      function setState (newState) {    
        memoizedStates[currentIndex] = newState    
        render()    
      }    
      return [memoizedStates[index++], setState]    
    }    
        
    function Counter() {    
      const [    
        number,    
        setNumber    
      ] = useState(0)    
      const [    
        title,    
        setTitle    
      ] = useState('随机标题')    
      return (    
        <>    
          <h1>{title}</h1>    
          <p>{number}</p>    
          <button    
            onClick={    
              () => setNumber(number + 1)    
            }    
          >    
            改数字    
          </button>    
          <button    
            onClick={    
              () => setTitle(`随机标题${Math.random()}`)    
            }    
          >    
            改标题    
          </button>    
        </>    
      )    
    }    
        
    function render() {    
      index = 0    
      ReactDOM.render(<Counter />, document.getElementById('root'));    
    }    
    render()


    现在已经完成了 useState 的基本原理,当你了解原理之后,使用 Hooks 就变得更加容易了。

  • 相关阅读:
    changing a pointer rather than erasing memory cells
    验证码识别 edge enhancement 轮廓增强 region finding 区域查找
    Manipulating Data Structures
    passing parameters by value is inefficient when the parameters represent large blocks of data
    Aliasing 走样
    Artificial Intelligence Research Methodologies 人工智能研究方法
    Thread safety
    include pointers as a primitive data type
    flat file
    functional cohesion
  • 原文地址:https://www.cnblogs.com/chenzxl/p/11827931.html
Copyright © 2011-2022 走看看