React-Hooks篇useState解析

81 阅读2分钟

1、useState使用方法

import { useState } from 'react';

export default function Counter() {
  const [count, setCount] = useState(0);

  function handleClick() {
    setCount(count + 1);
  }

  return (
    <button onClick={handleClick}>
      You pressed me {count} times
    </button>
  );
}

以上是官网的例子,从中可是了解到

  • useState返回的是一个数组,数组第一个值是当前需要改变状态的值;
  • 第二个为一个方法,方法是用于设置改变当前值的的;
  • useState有一个参数,参数是用来设置初始值的,可以是常量也可以是一个函数。

2、useState简单版的实现

实现思路:

  • 全局状态存储:这不同于 React 的实际实现,后者会为每个组件实例和每个 hook 调用维护独立的状态;
  • useState 函数:接受一个初始值 initialValue,如果 state 未初始化,则将其初始化为 initialValue,返回当前状态 state 和一个更新状态的函数 setState
  • setState 函数:更新全局状态 state,调用 render 模拟 React 的重新渲染。
  • 组件 MyComponent:调用自定义的 useState,获取状态和更新状态的函数,模拟了用户点击按钮的处理函数 handleClick
  • 渲染过程render 函数模拟了 React 的渲染过程,每次状态更新都会重新调用 MyComponent
  • 模拟用户交互:通过调用 setStateCallback 模拟用户点击按钮,更新状态并触发重新渲染。
// 用于存储状态的全局变量
let state;
let setStateCallback;

function useState(initialValue) {
  // 如果 state 未初始化,则初始化为传入的初始值
  if (state === undefined) {
    state = initialValue;
  }

  // 定义一个设置状态的函数
  function setState(newValue) {
    state = newValue;
    // 模拟 React 渲染
    render();
  }

  // 返回当前状态和设置状态的函数
  return [state, setState];
}

// 模拟一个简单的组件
function MyComponent() {
  // 使用自定义的 useState
  const [count, setCount] = useState(0);

  console.log('MyComponent Rendered with count:', count);

  // 模拟用户点击按钮来增加计数
  function handleClick() {
    setCount(count + 1);
  }

  return { handleClick };
}

// 模拟 React 的渲染过程
function render() {
  // 重新渲染组件
  const componentInstance = MyComponent();

  // 暴露组件实例的 handleClick 以便调用
  setStateCallback = componentInstance.handleClick;
}

// 初始渲染
render();

// 模拟用户交互
console.log('Initial state:', state);
setStateCallback();
console.log('State after one click:', state);
setStateCallback();
console.log('State after two clicks:', state);