Re: 新手让网页 act 起来: Day15 - 探索 useState (1)

前言

经过前面几篇基础介绍,应该对 useState 与 useEffect 有一定程度的认识,俗话说:「打铁要趁热」,再继续介绍其他的 Hooks 之前,这两天我们就透过之前所学来刻一个 useState ,藉由这个机会来更加了解这个 hook。

myUseState

下面是之前介绍 useState 的计数器范例。但我们做了一个更改就是将 React.useState() 换成 MyUseState(),所以目前这段程序码是完全坏掉的。

const Counter = () => {
  const [count, setCount] = myUseState(0)

  const increaseHandler = () => {
    setCount(count + 1) 
  }

  const decreaseHandler = () => {
    if (count === 0) return

    setCount(count - 1)
  }

  return (
    <div className="container">
      <button className="minus" onClick={decreaseHandler}>-</button>
      <span className="number">{count}</span>
      <button className="plus" onClick={increaseHandler}>+</button>
    </div>
  )
};

ReactDOM.render(<Counter />, document.getElementById('root'))

接下来就来一步步实作 myUseState 吧!

我们先来想想看对於 useState 最基本的了解:

  1. 接收一个任意基本型别做为 initialValue 并回传一个阵列
  2. 回传的阵列有两个值,分别是 state 与一个设定 state 的函式
  3. 当我们使用 setState 的时候,我们会更新 state 并触法 re-render。

依照上面所知的线索我们可以先完成基本的雏形:

function myUseState(initialValue){
    let state = initialValue
    
    function setState(newValue){
    // update state
    // call re-render
    }

  return [state, setState]
}

re-render 的部分我们可以先尝试重新让 ReactDOM.render 重新呼叫一次来达成:

function myUseState(initialValue){
  let state = initialValue
    
  function setState(newValue){
    // update state
    callRender()
  }

  return [state, setState]
}


function callRender(){
  ReactDOM.render(<Counter />, document.getElementById('root'))
}

callRender()

再来就是如何更新 state 并且再每一次的呼叫会丢出更新的值。如果说更新的 state 与现在一样就不会 re-render。

依照目前的雏形,当我们传入新的值到 setState 无法直接去更改 myUseState 中的 state 变数。就算改变了,後面触发 re-render ,myUseState 会重新被被呼叫 iniialValue 传进来的还是一开始的预设值,最後回传的还是预设值。

所以我们必须在 myUseState 外面的 scope 将值先存起来

let newStateValue

function myUseState(initialValue){
  if (newStateValue) return [newStateValue, setState]
  let state = initialValue
    
  function setState(newValue){
    if (newStateValue === newValue) return
    
    newStateValue = newValue
    callRender()
  }

  return [state, setState]
}

来看一下画面,计数功能就恢复正常了,一个非常非常基本的 useState 就完成了~~

虽然目前看起来功能是正常的,但事实上还缺很多东西,例如: setState 是要能够传入 callback 并更新 state 或是我们能够在一元件定义呼叫多个 myUseState 等等。

明天我们将继续完成它!如果对於今天的内容有问题都欢迎在下方留言~~

该文章同步发布於:我的部落格


<<:  【Day 15】Python MySQL

>>:  [Day 15]呐呐,还有一半别想跑(前端篇)

[Day 6] .Net WhenAll 底层(1)

前言 这系列教学文的目的是要探索具备非同步功能的框架在底层发生了什麽事, 甚至写一个简单的框架出来,...

[Day 03]取得Nonce与HashID以产出Sign - [C#]丰收款API必备前置作业(二)

首先来个永丰官方的文件图片作开场吧! (图一:由商户->永丰正向发动的所需参数) 而我们今天要...

Day17 - 汇出 excel-测试篇

前言 上篇题到如何制作产 Excel 档,这篇以撰写测试为主 说明 延续上篇完成的补写测试,这边还有...

JS中的排序法_上

在Day7时候有提到排序法的简介,并且简介常见的6个演算法,在Icebear学习5天JS语法之後,在...

[Day 06] (验收)小统整 - [C#]丰收款API必备前置作业(五)

先来复习一下永丰金流API需要准备的材料(?)有哪些吧~ 其实我们必要的API串接参数都已经准备得差...