美文网首页
useState 原理

useState 原理

作者: bestCindy | 来源:发表于2022-06-04 19:07 被阅读0次

首先回顾一下 useState 的用法

import React, { useState } from 'react';

function App() {
  const [n, setN] = useState(0);

  return (
    <div>
      <button onClick={() => setN(n+1)}>Click me</button>
      {n}
    </div>
  );
}

export default App;
  • useState: 返回数据 n 和更改数据的函数 setN
  • setN: 修改 n,

我们来实现 useMyState

let _state;
const useMyState = (intiState) => {
  _state = _state ?? intiState;
  const setState = (newState) => {
    _state = newState;
    render();
  }
  return [_state, setState];
}

const render = () => ReactDOM.render(<App />, document.getElementById('root'));

function App() {
  const [n, setN] = useMyState(0);
  return (
    <div>
      <p>{n}</p>
      <button onClick={() => setN(n+1)}>Click me</button>
    </div>
  )
}

render();

有多个 state 的情况呢

// 这就是为什么 React 不允许在 if...else... 里面调用 hooks
let _state = [];
let index = 0;

const useMyState = (intiState) => {
  let currentIndex = index;

  _state[currentIndex] = _state[currentIndex] ?? intiState;
  const setState = (newState) => {
    _state[currentIndex] = newState;
    index = 0;
    render();
  }

  index+=1;
  return [_state[currentIndex], setState];
}

const render = () => ReactDOM.render(<App />, document.getElementById('root'));

function App() {
  const [n, setN] = useMyState(0);
  const [m, setM] = useMyState(0);

  return (
    <div>
      <p>{n}</p>
      <button onClick={() => setN(n+1)}>Click me</button>
      <p>{m}</p>
      <button onClick={() => setM(n+1)}>Click me</button>
    </div>
  )
}

render();

useState 中的闭包问题

由于 React Hooks 是函数式组件,在异步操作或者使用 useCallBackuseEffectuseMemo的时候会形成闭包

举个例子

import React, { useState } from 'react';

function Demo() {
  const [num, setNum] = useState(0);

  const handleClick = () => {
    setTimeout(() => {
      alert(num)
    }, 3000)
  };

  return (
    <div>
      <div>当前点击了{num}次</div>
      <button onClick={() => { setNum(num + 1)}}>点我</button>
      <button onClick={handleClick }>展示现在的值</button>
    </div>
  )
}

export default Demo;

现在我们:

  1. 点击 “点我” 增加到 1
  2. 点击 “展示现在的值”
  3. alert 之前,点击 “点我”,让 num 增加到 2

结果是这样的:

现在用 class 组件 refactor 一编

class Demo extends React.Component {
  stete = {
    num: 0
  }

  handleClick = () => {
    setTimeout(() => {
      alert(this.state.num);
    }, 3000)
  }

  render() {
    const { num } = this.state;
    return (
      <div>
        <div>当前点击了{num}次</div>
        <button onClick={() => { this.setState({ num : num + 1}) }}>点我</button>
        <button onClick={this.handleClick }>展示现在的值</button>
      </div>
    )
  }
}

重复之前的步骤:

从这个例子可以看出,React Hooks 在某一个特定渲染中 stateprops 是与其绑定的,然而类组件并不是

解决 useState 中的闭包问题

function Demo() {
  const nRef = React.useRef(0); // nRef 是一个对象 { current: 0 }

  const handleClick = () => {
    setTimeout(() => {
      alert(nRef.current);
    }, 3000);
  }

  return (
    <div>
      <p>当前点击了{nRef.current}次</p>
      <button onClick={() => (nRef.current += 1)}>点击</button>
      <button onClick={handleClick}>展示现在的值</button>
    </div>
  )
}

我们用 nRef 解决了闭包的问题,但是现在有另一个问题,UI 并不会重新渲染

这时候要用到 useState 触发更新


function Demo() {
  const nRef = React.useRef(0); // nRef 是一个对象 { current: 0 }
  const update = React.useState()[1];

  const handleClick = () => {
    setTimeout(() => {
      alert(nRef.current);
    }, 3000);
  }

  return (
    <div>
      <p>当前点击了{nRef.current}次</p>
      <button onClick={() => ((nRef.current += 1), update(nRef.current))}>点击</button>
      <button onClick={handleClick}>展示现在的值</button>
    </div>
  )
}

相关文章

  • useState原理

    首先创建一个App组件,加入一个按钮和点击后显示的值num,在按钮上绑定click事件,每次点击,num++ 在首...

  • useState原理

    首次渲染 ——调用App(),得到虚拟DOM1,把虚拟DOM1渲染成真实DOM用户点击button后,调用setN...

  • useState 原理

    useState用法 点击button会发生什么? 分析: setNsetN一定会修改数据x, 将n+1存入xse...

  • useState 原理

    首先回顾一下 useState 的用法 useState: 返回数据 n 和更改数据的函数 setN setN: ...

  • useState 实现原理

    useState 熟悉hooks的都知道,最常用的useState 大概用法 简单的实现一个useState 先模...

  • 【理论】useState原理

    Hook 是 React 16.8 的新增特性,所以使用Hook 时要保证React版本在16.8及以上。npm ...

  • useState使用和原理

    没有hooks 的useState 时,我想改变状态是这样的是在类组件中使用状态通过 state 定义

  • 依据React Hooks的原理,写一个简易的 useEffec

    之前根据 react hooks 的原理实现了一个简易的 useState[https://www.jianshu...

  • 依据React Hooks的原理,写一个简易的 useEffec

    之前根据 react hooks 的原理实现了一个简易的 useState[https://www.jianshu...

  • React hooks的useState原理

    useState的基本用法 问自己几个问题 1.执行setN的时候会发生什么?n会变吗?App()会重新执行吗?2...

网友评论

      本文标题:useState 原理

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