从原理上解读useState钩子函数

简介: 从原理上解读useState钩子函数

原生useState具有的几个特点

  1. 返回一个数组,数组的第一个参数值是状态值,第二个参数值是设置状态的方法。
  2. useState会判断传入的state是初始值还是已存在的值。
  3. useState可能被多次调用
  4. 调用设置状态的方法后需要重新渲染组件。

手写useState

第一步:用不同的数组来分别存放状态值和设置状态的方法

let states = [];
let setters = [];
let stateId = 0;
复制代码

第二步:判断useState传入的初始状态值是否已经存在

存在用以前的,不存在则使用初始状态值

states[stateId] = states[stateId] ? states[stateId] : initialState;
复制代码

第三步:通过状态的id来返回设置状态的方法,然后加入到设置方法的数组中

注意:自定义的渲染函数必须能够操作全局的状态id.

setters.push(createSetter(stateId));
function createSetter(stateId) {
    return function (newState) {
        states[stateId] = newState;
        myRender();
    }
}
function myRender() {
    stateId = 0;
    ReactDOM.render(<App />, document.querySelector('#root'));
}
复制代码

第四步:返回第i个状态值和操作状态的方法,并对stateId+1

let value = states[stateId];
let setter = setters[stateId];
stateId++;
return [value, setter]
复制代码

完整代码

import React from 'react'
import ReactDOM from 'react-dom'
// 自定义Hook
/**
 * @description: 手写useState
 * @param {*}
 * @return {*}
 */
let states = [];
let setters = [];
let stateId = 0;
function createSetter(stateId) {
    return function (newState) {
        states[stateId] = newState;
        myRender();
    }
}
function myRender() {
    stateId = 0;
    ReactDOM.render(<App />, document.querySelector('#root'));
}
function myUseState(initialState) {
    // 判断state是否存在,存在则使用以前的,不存在则使用初始值
    states[stateId] = states[stateId] ? states[stateId] : initialState;
    setters.push(createSetter(stateId));
    let value = states[stateId];
    let setter = setters[stateId];
    stateId++;
    return [value, setter]
}
function App() {
    const [count, setCount] = myUseState(0);
    const [name, setName] = myUseState('张三');
    return (
        <div>
            <h1>当前求和为:{count}</h1>
            <button onClick={() => setCount(count + 1)}>点我+1</button>
            <h1>当前姓名为:{name}</h1>
            <button onClick={() => setName('李四')}>点我切换姓名</button>
        </div>
    )
}
ReactDOM.render(<App />, document.querySelector('#root'));
复制代码

CodeSandBox在线实现地址

参考资料

相关文章
|
前端开发 JavaScript
深入理解React中的useEffect钩子函数
深入理解React中的useEffect钩子函数
114 0
|
前端开发 JavaScript 安全
useEffect 与 useLayoutEffect区别
useEffect 与 useLayoutEffect区别
86 0
|
2月前
|
存储 前端开发 JavaScript
useRef 钩子使用技巧
【10月更文挑战第12天】本文详细介绍了 React 中的 `useRef` Hook,包括其基础概念、基本用法、常见问题与易错点以及如何避免这些问题。通过具体代码示例,解释了 `useRef` 的应用场景,如保存对 DOM 元素的引用、保存回调函数和定时器 ID 等,帮助开发者更有效地使用这一工具。
117 14
|
2月前
|
前端开发 开发者
useContext 钩子详解
【10月更文挑战第14天】`useContext` 是 React 中的一个 Hook,用于在组件树中传递数据,避免手动传递 props。本文从基本概念、使用方法、常见问题及解决方法等方面详细介绍了 `useContext`,并提供了代码示例,帮助开发者更好地理解和应用这一钩子。
75 5
|
2月前
|
前端开发 JavaScript
useReducer 钩子实战
【10月更文挑战第13天】在 React 中,`useState` 是常用的状态管理钩子,但面对复杂状态逻辑时,`useReducer` 提供了更结构化的方式。本文从基础到进阶介绍 `useReducer` 的使用方法、常见问题及解决方案,并通过计数器和表单组件的示例加深理解。
50 3
|
2月前
|
前端开发 JavaScript 开发者
useEffect 钩子详解与实战
【10月更文挑战第3天】React 作为一个流行的 JavaScript 库,通过 Hooks 大幅简化了组件开发。`useEffect` 是一个核心 Hook,用于处理函数组件中的副作用操作,如数据获取和 DOM 更改。本文详细介绍了 `useEffect` 的基本语法、常见用法及示例,包括模拟 `componentDidMount`、`componentDidUpdate` 和 `componentWillUnmount`。此外,还探讨了如何避免无限循环渲染和内存泄漏等问题,并提供了相应的解决方案,帮助开发者更好地理解和应用 `useEffect`,提升应用程序的性能与稳定性。
60 7
|
5月前
|
前端开发 JavaScript 数据格式
react18【系列实用教程】Hooks (useState,useReducer,useRef,useEffect,useContext,useMemo,useCallback,自定义 Hook )
react18【系列实用教程】Hooks (useState,useReducer,useRef,useEffect,useContext,useMemo,useCallback,自定义 Hook )
106 1
|
7月前
|
前端开发 JavaScript 开发者
掌握React中的useEffect:函数组件中的魔法钩子
掌握React中的useEffect:函数组件中的魔法钩子
|
JavaScript
useEffect和useLayoutEffect有什么区别
useEffect和useLayoutEffect有什么区别
|
7月前
|
前端开发 JavaScript
React 钩子:useState()
React 钩子:useState()
79 0
React 钩子:useState()

热门文章

最新文章