React Hooks - Day1


Posted by rockyooooooo on 2021-08-13

React Hooks

Day1

[Day 01] 沒學過 React 可以從 Hooks 開始嗎?
[Day 02] React 中一定會用到的 JavaScript 語法

心態建立

沒有學過 React,反而可能是優勢。

Redux 的作者 Dan Abramov 說過:

Hooks 是一個新的思維方式,所以有時候你要忘掉原本學過的,反而更能幫助你學習新的東西。

需要具備的能力

  • HTML
  • CSS
  • JavaScript

你該不會該好都學過吧?

那就可以開始寫 React Hooks 了!

React 中會用到的 ES6 語法

樣板字面值 (Template literal / Template String)

將原本字串用 ' 包起來的符號改成 ` 包起來,並在需要放入表達式的地方用 ${} 包起來。

const name = 'AllenLiao'
console.log(`The most handsome person: ${name}`)
// 'The most handsome person: AllenLiao'

箭頭函式 (Arrow Function)

一般宣告函式

function showTheBestSinger(name) {
  return `小樹屋靈魂歌姬:${name}`
}

console.log(showTheBestSinger('Didi'))
// '小樹屋靈魂歌姬:Didi'

用 Function Expression 搭配箭頭函式

const showTheBestSinger = (name) => {
  return `小樹屋靈魂歌姬:${name}`
}

console.log(showTheBestSinger('Didi'))
// '小樹屋靈魂歌姬:Didi'

帶入的參數只有一個時可以省略 ()

const showTheBestSinger = name => {
  return `小樹屋靈魂歌姬:${name}`
}

console.log(showTheBestSinger('Didi'))
// '小樹屋靈魂歌姬:Didi'

如果沒有參數則一定要加 ()

const showTheBestSinger = () => {
  return `小樹屋靈魂歌姬:Didi`
}

console.log(showTheBestSinger())
// '小樹屋靈魂歌姬:Didi'

function 的內容只有一行的話可以省略 {}

const showTheBestSinger = name => `小樹屋靈魂歌姬:${name}`

console.log(showTheBestSinger('Didi'))
// '小樹屋靈魂歌姬:Didi'

前後比較

function showTheBestSinger(name) {
  return `小樹屋靈魂歌姬:${name}`
}

console.log(showTheBestSinger('Didi'))
// '小樹屋靈魂歌姬:Didi'

const showTheBestSinger = name => `小樹屋靈魂歌姬:${name}`

console.log(showTheBestSinger('Didi'))
// '小樹屋靈魂歌姬:Didi'

少打很多字超爽der

物件屬性縮寫

當物件的屬性名稱,跟指定給屬性當值的變數名稱相同時,可以省略屬性值不寫。

const nickname = '大 ben'
const petPhrase = '??'
const ben = {
  nickname: nickname,
  petPhrase: petPhrase
}

console.log(ben.petPhrase) // '??'

const nickname = '大 ben'
const petPhrase = '??'
const ben = {
  nickname,
  petPhrase
}

console.log(ben.petPhrase) // '??'

解構賦值 (Destructuring Assignment)

帥氣並快速的建立變數並取出物件或陣列中的值。

物件的解構賦值

一般從物件取出屬性值,並建立新的變數。

const angelina = {
  nickname: '安你老師',
  personality: '很兇',
  interest: '叫別人念咒語'
}

const personality = angelina.personality // '安你老師'

使用解構賦值可以把物件的屬性值,賦值給該屬性的同名變數。

const angelina = {
  nickname: '安你老師',
  personality: '很兇',
  interest: '叫別人念咒語'
}

const { nickname, interest } = angelina
console.log(`${nickname}喜歡${interest}`)
// '安你老師喜歡叫別人念咒語'

陣列的解構賦值

一般從陣列的值建立新的變數:

const handsomeThree = ['Allen', 'Jason', 'Hsuan']
const first = handsomeThree[0] // 'Allen'
const second = handsomeThree[1] // 'Jason'
const third = handsomeThree[2] // 'Hsuan'

※以上順序不是依照帥氣程度

使用解構賦值,建立變數並賦予陣列相對應的位置的值。

const handsomeThree = ['Allen', 'Jason', 'Hsuan']
const [first, second, third] = handsomeThree
console.log(first) // 'Allen'
console.log(second) // 'Jason'
console.log(third) // 'Hsuan'

※以上順序不是依照帥氣程度

展開語法和其餘語法 (Spread Syntax / Rest Syntax)

使用在物件跟陣列上,同樣是用 ...,但使用的時機不同

展開語法 (Spread Syntax)

可以將陣列或物件「解壓縮」,而且可以同時新增新的值。

陣列:

const array = [1, 2, 3]
const newArray = [...array, 4, 5]

console.log(array) // [1, 2, 3]
console.log(newArray) // [1, 2, 3, 4, 5]

物件:

const sisi = {
  name: 'Sisi',
  habit: '崩潰'
}
const newSisi = {
  ...sisi,
  name: 'Paimia',
  nickname: '背殺'
}

console.log(sisi) // {name: 'Sisi', habit: '崩潰'}
console.log(newSisi)
// {name: 'Paimia', habit: '崩潰', nickname: '背殺'}

因為原物件已經有 name 屬性,新物件的 name 會覆寫原物件的 name

其餘語法 (Rest Syntax)

將物件或陣列沒被取出來的屬性或元素「壓縮」。

陣列:

const superJuniors = [
  'Allen', 'Jason', 'Angelina', 
  'Benben', 'Didi', 'a_u_z', 
  'sixwing', 'Raye', 'rich'
]
const [handsome, alsoHandsome, ...others] = superJunior
console.log(handsome) // 'Allen'
console.log(alsoHandsome) // 'Jason'
console.log(others)
// [
//   'Angelina', 'Benben', 'Didi', 
//   'a_u_z', 'sixwing', 'Raye', 'rich'
// ]

物件:

const titles = {
  hooks: ['Allen', 'a_u_z', 'rich'],
  leetcode: ['Angelina', 'Benben', 'Raye'],
  es6: ['sisi', 'Jason', 'Didi'],
  css: ['a', 'b', 'c'],
  html: ['d', 'e', 'f']
}
const { hooks, leetcode, es6, ...losers } = titles
console.log(losers) // {css: Array(3), html: Array(3)}

不管是展開語法還是其餘語法,... 都是淺拷貝(Shallow Copy)。

const arr1 = [1, [2]]
const arr2 = [...arr1]
arr2[1][0] = 22
console.log(arr1[1][0]) // 22

補充

表達式(Expressions)和 陳述句(Statements)

表達式(Expressions)

An expression is any valid unit of code that resolves to a value.
表達式是任何一段可以取得一個值的程式碼。

Expressions 有兩種形式:

  1. 有副作用的,ex:x = 7
  2. 只為了取得值而解析的,ex:3 + 4

簡單來說,只要在瀏覽器的 console 打程式碼,如果有回傳值,就是 Expressions。


圖片來源:[筆記] 進一步談JavaScript中函式的建立─function statements and function expressions

陳述句(Statements)

研究了一陣子,還是沒辦法知道定義是什麼,頭好痛。

根據 重讀 Axel 的 Javascript 中的 Expression vs Statement 一文 的說法,Statements 就是執行動作、完成特定任務。例如賦值、迴圈、if、else 等,都是 Statements。

還有一些長得很像 Statements 的 Expressions,詳情請看:重讀 Axel 的 Javascript 中的 Expression vs Statement 一文

Function Statements 和 Function Expressions

Function Statements

function greet() {
  console.log('Hi')
}

上面的程式碼是 Function Statement,也叫做 Function Declaration,就是最一般的宣告函式的方法。

greet()  // 'Hi'

function greet() {
  console.log('Hi')
}

因為 JavaScript 的 Hoisting 特性,我們可以在宣告 greet 之前就先執行他。

Function Expressions

const greet = function() {
  console.log('Hi')
}

跟 Function Statements 不一樣,Function Expressions 是宣告一個變數,再把一個匿名函式賦值給他。

用 Function Expressions 的方式,就沒辦法在宣告之前就執行他了。

greet()
// ReferenceError: Cannot access 'greet' before initialization

const greet = function() {
  console.log('Hi')
}

依照 Hoisting 的特性,只有宣告會提升,賦值不會,我覺得蠻合理的。

淺拷貝和深拷貝(Shallow Copy / Deep Copy)

淺拷貝

在複製物件或陣列時,只有第一層是複製值,第二層開始是複製位址。

深拷貝

在複製物件或陣列時,每一層都是乖乖的複製值過去。

const arr = [1, [2]]
const shallowCopyArr = [...arr]
const deepCopyArr = JSON.parse(JSON.stringify(arr))
shallowCopyArr[1][0] = 22

console.log(arr) // [1, [22]]
console.log(shallowCopyArr) // [1, [22]]
console.log(deepCopyArr) // [1, [2]]

參考資料:

  1. [筆記] 進一步談JavaScript中函式的建立─function statements and function expressions
  2. 表達式(Expressions)
  3. 重讀 Axel 的 Javascript 中的 Expression vs Statement 一文
  4. 覺得 JavaScript function 很有趣的我是不是很奇怪
  5. JavaScript 淺拷貝 (Shallow Copy) 與深拷貝 (Deep Copy)
tags: Super Junior

#javascript #React







Related Posts

先別急著學 React

先別急著學 React

Advanced JS  (上)

Advanced JS (上)

Letter Combinations of a Phone Number

Letter Combinations of a Phone Number


Comments