React深入学习useState

简介: React深入学习useState

useState是React自带的一个方法,用于操作和重新渲染UI

今天我就来刨析以下useState到底是怎么实现的,并且自己构造一个与useState相同的方法myUseState

以实现一个+1的案例为模板


React自带的API useState


const App =()=>{
  const [n,setN] = useState(0);
  return(
    <div>
      n:{n}
      <button onClick={add=>{setN(n+1)}}>+1</button>
    </div>
  )
}

const [n,setN] = useState(0);这一句看着是不是很迷惑,即使学了前面的基础知识看到这一句还是有点疑惑

其实useState是一个是函数,0是传入的参数,把传入的参数赋值给了n,而setN也是一个函数

是不是还是有点迷茫???

我们自己构造一个useState函数就可以很好的理解它


自己构造useState函数


首先约定_state就相当于[n,setN]里的n, setState就等于setN_initValue接受调用myUseState传入的参数_state = _state ===undefined?initValue:_state这一句是第一次调用参数时将拿到的参数值赋值给_state;如果不是第一次调用则将最新的_state值赋值给他自己setState就是将拿到的新值进行操作渲染,newState参数就相当于setN(n+1)中的参数n+1;新值变化后就先赋值给_state然后就渲染到页面上return [_state,setState]将得到的新值_state和操作函数setState当作结果给返回n,和setN只不过是接受返回的参数,可以随便定义,但是要与下面使用相匹配

import React from 'react'
import ReactDOM from 'react-dom'
// initValue是初始值,接收传入的参数n
let _state;
const myUseState=(initValue)=>{
 _state = _state ===undefined?initValue:_state;
 const setState=(newState)=>{
   _state = newState;
  ReactDOM.render(<App />,document.getElementById('root'));
 };
 return [_state,setState]
}
const App =()=>{
 const [n,setN] = myUseState(0);
 return(
   <div>
     n:{n}
     <button onClick={add=>{setN(n+1)}}>+1</button>
   </div>
 )
}
ReactDOM.render(<App />,document.getElementById('root'));

这个时候就有那么一丝丝明悟了

但是这样还是有bug,只能接受和改变一个n,如果再创建一个m,  const [n,setN] = myUseState(0),当你点击n+1的时候m也会同时+1

怎样做到接收多个参数呢?点击哪个就让哪个+1;而另一个不变呢?

解决方法:可以使用数组,将多个参数接收;用index判断使用那一个参数


myUseState接收多个参数


把_state变成数组类型,使用index判断改变的是哪一个currentIndex作为中间变量,保存index的值,因为index是变化的(index+=1),如果不使用currentIndex那么_state指向的就是下一个值

在渲染之前要把index归零,否则作为index的下标一直在在+1,会将数组扩大

import React from 'react'
import ReactDOM from 'react-dom'
// initValue是初始值,接收传入的参数n
let _state=[];
let index=0;
const myUseState=(initValue)=>{
 const currentIndex = index
 _state[currentIndex] = _state[currentIndex] ===undefined?initValue:_state[currentIndex];
 const setState=(newState)=>{
   _state[currentIndex] = newState;
  render();
 };
 index+=1;
 return [_state[currentIndex],setState]
};
const render=()=>{
 index=0
 ReactDOM.render(<App />,document.getElementById('root'));
}
const App =()=>{
 const [n,setN] = myUseState(0);
 const [m,setM] = myUseState(0);
 return(
   <>
     <div>
       n:{n}
       <button onClick={()=>{setN(n+1)}}>+1</button>
     </div>
     <div>
       m:{m}
       <button onClick={()=>{setM(m+1)}}>+1</button>
     </div>
   </>    
 )
}
ReactDOM.render(<App />,document.getElementById('root'));

这时的setState就比较完善了,但是还是有一些缺点的


_state数组方案缺点:


useState调用顺序:若第一次渲染时n是第一个,m是第二个,k是第三个则第二次渲染时必须保证顺序完全一致;所以不能出现if... else等改变顺序的代码\

总结:


  • 每个函数组件对应一个React节点
  • 每个节点保存着state和index
  • useState会读取state[index]
  • index由useState出现的顺序决定setState会修改state,并触发更新


useState注意事项:


1.不可局部更新:

如果state是一个对象,不能更新一部分数据,因为setState不会合并数据,要使用...先将数据赋值过来

2.地址要变:

setState(obj)如果obj地址不变,那么React就认为数据没有变化

3.接受函数:

可以在初始化时(useState)

const[state,setState]= usestate(()=>{
return initialstate
})

该函数返回初始state,且只执行一次

setState传入函数

setN( i => i+1 )


目录
相关文章
|
7月前
|
缓存 前端开发 JavaScript
学习React的最佳实践有哪些?
学习React的最佳实践有哪些?
284 86
|
前端开发 JavaScript
学习react基础(3)_setState、state、jsx、使用ref的几种形式
本文探讨了React中this.setState和this.state的区别,以及React的核心概念,包括核心库的使用、JSX语法、类与函数组件的区别、事件处理和ref的使用。
178 3
学习react基础(3)_setState、state、jsx、使用ref的几种形式
|
12月前
|
前端开发 JavaScript
React学习之——条件渲染
【10月更文挑战第16天】React 中没有像Vue中v-if这种指令。React 中的条件渲染和 JavaScript 中的一样,使用 JavaScript 运算符 if 或者条件运算符去创建元素来表现当前的状态,然后让 React 根据它们来更新 UI。
|
11月前
|
前端开发 JavaScript
深入探索React Hooks:从useState到useEffect
深入探索React Hooks:从useState到useEffect
|
前端开发
学习react基础(2)_props、state和style的使用
本文介绍了React中组件间数据传递的方式,包括props和state的使用,以及如何在React组件中使用style样式。
163 0
|
7月前
|
前端开发 JavaScript API
如何快速学习React?
如何快速学习React?
206 1
|
11月前
|
前端开发
深入探索React Hooks:从useState到useEffect
深入探索React Hooks:从useState到useEffect
131 3
|
11月前
|
前端开发 JavaScript 安全
学习如何为 React 组件编写测试:
学习如何为 React 组件编写测试:
132 2
|
资源调度 前端开发 JavaScript
React进阶学习
React进阶学习
95 1
|
前端开发
react学习(17)回调形式的ref
react学习(17)回调形式的ref
139 9