当前位置:   article > 正文

usestate 数组增加_React Hook -- useState

usestate设置数组

ee3022d71c95d6d11b9af141e4cbdbbd.png

本文用来记录和回顾react hook 的使用,因为react的函数式组件式本身是没有状态的和其他类似于class组件的功能,所以一开始,函数组件一般只作为容器组件存在,用来展示父级组件传入的值。而16.8之后出现的 hooks(钩子),打开了函数式组件的新大门。

useState

作用:用来记录函数式组件的状态

使用方式

import React, { useState } from 'react'

const [n, setN] = React.useState(0)

举个 ,做一个简单的计数器,可以增加和减少

  1. import React, { useState } from 'react‘
  2. import ReactDOM from 'react-dom‘
  3. const App: React.FC = (props: any) => {
  4. const [n, setN] = useState(0)
  5. const handlePlus = () => {
  6. setN(n+1)
  7. }
  8. const handleMinus = () => {
  9. setN(n-1)
  10. }
  11. return (
  12. <div>
  13. <span>{ n }</span>
  14. <button onClick={ handlePlus }>+1</button>
  15. <button onClick={ handleMinus }>-1</button>
  16. </div>
  17. )
  18. }
  19. ReactDOM.render(<App />, document.getElementById('root‘))

此时就能记录该计数器的状态了。

使用注意事项:

  1. 不可以局部更新

如果我们创建的state是一个对象,是否能只更改state中的某个属性。

  1. const [user, setUser] = useState({
  2. name: 'habitat‘,
  3. age: 18
  4. })
  5. // 如果我只想修改其中的name属性
  6. <button onClick={() => { setName('ck') }}>change name </button>
  7. // 预期的话 只会改变其中的name属性,并保留age属性
  8. // 但是实际上 user会直接变成 { name: 'ck‘ },而不保留age属性
  9. // 正确操作是浅拷贝原来的所有属性,然后用新的属性覆盖老的属性
  10. <button onClick={ () => { setName({ ...user, name: 'ck' )} }>change name </button>

2. setXX(obj)如果重新修改对象,其对象地址一定要改变,如果没有改变react就不能监听到其变化。

探究useState如何实现

第一次尝试

  1. // 尝试改写 React.useState
  2. function myUseState(initialValue) {
  3. var state = initialValue
  4. const setState = (newState) => {
  5. state = newState
  6. // 更新页面
  7. render()
  8. }
  9. return [state, setState]
  10. }
  11. const render = () => ReactDOM.render(<App />, document.getElementById('root‘))
  12. const App: React.FC = (props: any) => {
  13. const [n, setN] = myUseState(0)
  14. const handlePlus = () => {
  15. setN(n+1)
  16. }
  17. const handleMinus = () => {
  18. setN(n-1)
  19. }
  20. return (
  21. <div>
  22. <span>{ n }</span>
  23. <button onClick={ handlePlus }>+1</button>
  24. <button onClick={ handleMinus }>-1</button>
  25. </div>
  26. )
  27. }
  28. ReactDOM.render(<App />, document.getElementById('root‘))

失败告终,因为每一次重新render的时候,会使用初始值去改变了原有的已经改变了的值,即myUseState会讲state重置。

第二次冲刺:

将state提升为全局变量

  1. let _state
  2. function myUseState(initialValue) {
  3. _state = _state === undefined ? initialValue : _state;
  4. const setState = (newState) => {
  5. _state = newState
  6. render()
  7. }
  8. return [_state, setState];
  9. }

此时利用全局变量,再一次渲染时,因为全局变量已经被修改了,所以重新渲染调用

const [n, setN] = useState(0)的时候,就不会被直接覆盖掉,所以暂时是成功。为什么说是暂时的呢,因为此时只能使用一个useState。如果使用多个useState的时候,则会导致有很多个全局变量,不好管理。

第三次尝试:

将state记录成数组,并使用index去进行创建和修改

  1. let _state = []
  2. let index = 0
  3. function myUseState(initialValue) {
  4. const currentIndex = index
  5. index += 1
  6. _state[currentIndex] = _state[currentIndex] || initialValue
  7. const setState = newState => {
  8. _state[currentIndex] = newState
  9. render
  10. }
  11. return [_state[currentIndex], setState]
  12. }
  13. const render = () => {
  14. //index重置为0
  15. index = 0
  16. ReactDOM.render(<App />, document.getElementById('root‘))
  17. }

将state记录成一个数组,当进行初始化时,每一次初始化都能记录到对应的下标,而改变时,也都能都对其对应下标进行改变。但是不能够条件性的进行初始化,这样的话会导致对应下标的数据错误。

总结:

每个函数组件都会对应一个React节点

每个节点都保存着state和index

useState会读取state[index]

index由useState的出现的顺序决定

setState会修改state,并触发更新

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Cpp五条/article/detail/660934
推荐阅读
相关标签
  

闽ICP备14008679号