[Day24] 在 Codecademy 学 React ~ 终於来到 Hook 的世界 ‧ useState 篇 (1)

前言

看到今天标题 useState
你可能会说我前面不是讲过了吗XD
其实之前那样算是直接跳过第一、二阶段,
直接来到第三阶段,
还记得前几天的文章我一直在跟 this.props, this.state,还有 this.setState 奋斗(?),
这算是第一阶段的看山是山,
今天的文章一开始会讲一点不用 this 的用法,这是第二阶段的看山不是山,
再来就会进入本日重头戏第三阶段的看山又是山 - useState 罗~
而且在 Codecademy 上进入 useState 学习之前,
我也是天真的以为我都会了,
没想到真的学了才发现有很多东西我还不会,
因此当作复习跟吸收新知,
大家就再跟着我的脚步来到 useState 的世界吧!

本日正文

不需要用 this 的 props 取用方法

还记得我们之前如果要宣告一个 componenet 都要落落长写这样的程序:

class XXX extends React.Component {
	render() {
		return (
		)
	}
}

而且如果要在 class 里面取用属性的值,
必须要写 this.props.属性
像这样:

<div>
	<h1>这是一个{this.props.name}</h1>
	<h1>颜色:{this.props.color}</h1>
	<h1>价格:{this.props.price}元</h1>
</div>

有个好消息,Codecademy 教了一个写法不用再写这麽落落长的语法,
这边把前几天写的范例再贴一次:

Fruit.js

export class Fruit extends React.Component {
  render() {
    return (
      <div>
        <h1>这是一个{this.props.name}</h1>
        <h1>颜色:{this.props.color}</h1>
        <h1>价格:{this.props.price}元</h1>
      </div>
    );
  }
}

现在我们只要写成这样就好罗!

export const Fruit = (props) => {
  return (
    <div>
      <h1>这是一个{props.name}</h1>
      <h1>颜色:{props.color}</h1>
      <h1>价格:{props.price}元</h1>
    </div>
  );
};

而且在 App.js 跟之前一样使用 <Fruit>
<Fruit name="莲雾" color="浅红色" price="200" />
发现就可以达成一样效果,这样的写法是不是简单很多呢?
https://ithelp.ithome.com.tw/upload/images/20210926/20129873uCTpZV4FPX.png

这就是第二阶段的写法,
接下来要进入第三阶段罗XD

Hook - useState

在 React 16.8+ 版本以後提供了 Hook 的方式,
让宣告及使用 componenet 变得更加简便,
常见的 Hook 有:useState(), useEffect(), useContext(), useReducer(), and useRef()
对完整的 Hook 有兴趣的人可以参考这篇→ Hooks API Reference

在正式进入 useState 之前,
让我们回忆一下,
之前在改变天气的例子中,
还记得我们是怎麽写的吗?

  1. 首先宣告一个 class Weather
export class Weather extends React.Component
  1. 里面要使用 constructor(props),里面还要宣告一个 weather 的 state
constructor(props) {
    super(props);
    this.state = { weather: "sunny" };
    
  }
  1. 再来还要宣告改变天气的 function changeWeather,里面要用到 this.setState
changeWeather() {
    const newWeather = this.state.weather === "sunny" ? "rainy" : "sunny";
    this.setState({ weather: newWeather });
  }
  1. 然後别忘了在 constructor 里面要把 changeWeather 跟 this bind 起来
this.changeWeather = this.changeWeather.bind(this);
  1. 在按钮的 onClick 事件宣告呼叫 this.changeWeather
  render() {
    return (
      <div>
        <h1>今天天气:{this.state.weather}!</h1>
        <button onClick={this.changeWeather}>改变天气</button>
      </div>
    );
  }
}

经过这 5 个步骤才能达到我们按按钮切换天气的功能,
可是你知道用 useState 改写後变得多轻松写意吗?

让我们来改写看看吧!

  1. 首先要在第一行 import { useState }
import React, { useState } from "react";
  1. 再来宣告 Weather 的 class,一样用上面提到的 const 语法即可
export const Weather = () => {  
};
  1. 再来在 Weather 的 class 里面宣告 weather 状态,并使用 useState
const [weather, setWeather] = useState('sunny');

这句的意思是 有一个 weather 状态,初始值用 useState 设为 sunny,
之後改变 weather 的 function 就是 setWeather。

Codecademy 对於 useState 的详细说明如下,
useState 包含两个值:current state(现在状态的值)、以及 state setter (改变状态的 function)

useState() is a JavaScript function defined in the React library. When we call this function, it returns an array with two values:
current state - the current value of this state
state setter - a function that we can use to update the value of this state

  1. 然後只要直接在按钮的 onClick 事件写 setWeather,
    不需要像之前还要再另外宣告 function 跟 bind this,
    像这样:
return (
    <div>
      <h1>今天天气:{weather}!</h1>
      <button
        onClick={() =>
          weather === 'sunny' ? setWeather('rainy') : setWeather('sunny')
        }
      >
        改变天气
      </button>
    </div>
  );

这边说明一下 weather === 'sunny' ? setWeather('rainy') : setWeather('sunny')
这句意思是,判断 weather 值是否为 'sunny',是的话就执行 setWeather 将 weather 值改为 'rainy',
不是的话就执行 setWeather 将 weather 值改为 'sunny'。

是不是简单很多!
也不用在那边写落落长的 constructor, props, function,
还会三不五时忘记 bind orz
用更简单的写法却能达成一样的效果,
React 真是造福人群QQ

今日范例虽然是改写之前的,
不过还是附上来→ Day24 - useState (Codecademy)

然後再附上两种写法的截图,
大家应该一看就觉得哪种写法比较简单又方便又好懂了吧XD
https://ithelp.ithome.com.tw/upload/images/20210926/20129873WuPCptlGSs.png

後记

其实这边只是初步介绍 useState,
算是再让大家感受一下从 this.state, this.setState 到 useState 的差别,
这样大家可能也比较能了解为什麽对於一开始就学 useState 写法的我来说,
要再跳回去写那些落落长的写法会有点适应不良了orz

Codecademy 对於 useState 的教学还有更进阶的用法,
就让我留到明天文章吧XD


<<:  D3JsDay11 观测时候别铁齿,拿出你的比例尺

>>:  day26 : k8s backup/restore/migrate with velero(上)

注意!所以会点开来!

Day15 - 注意力连接情绪的发想 在教授丹尼尔,列维汀着作的《有序》一书当中,我发现很有趣的一点...

Day29 小孩子才做选择

Which is better? Modification or construction? 虽然...

#8-选单华丽开起来!超简单!(animation-delay)

昨天做完了会动的汉堡动画传送门 今天来开关侧边栏吧! 当然只要控制 width0 —> 100...

[Day15] 补充说明 – Cookie、Session和Token之Part2

哈罗夥伴们,我们今天要来解释解释,昨天的故事到底在说甚麽~~ 这里的A可以想成是客户端,银行想成是服...

【从实作学习ASP.NET Core】Day29 | 补充 | 图表 Chart.js

网站大致完成了,今天就来介绍 Chart.js 这个免费的资料视觉化套件 Chart.js Char...