與我使用過的其它框架相比,我最喜歡 React 的一點是,當你使用它時與 JavaScript 的密不可分。不存在模版 DSL(JSX 直接編譯成 JavaScript),組件 API 在添加了 React Hooks 後變得更加簡單,而且這個框架在它想要解決的核心 UI 關注點之外提供的抽象概念很少。
因此,學習 JavaScript 特性對於您更高效地使用 React 構建應用程式絕對是明智的。下面是一些我建議您花一些時間學習的 JavaScript 特性,從而讓你儘可能高效地使用 React 工作。
React Hooks: https://reactjs.org/hooks
const greeting = 'Hello'
const subject = 'World'
console.log(`${greeting} ${subject}!`)
console.log(greeting + ' ' + subject + '!')
function Box({className, ...props}) {
return <div className={`box ${className}`} {...props} />
}
const a = 'hello'
const b = 42
const c = {d: [true, false]}
console.log({a, b, c})
console.log({a: a, b: b, c: c})
function Counter({initialCount, step}) {
const [count, setCount] = useCounter({initialCount, step})
return <button onClick={setCount}>{count}</button>
}
const getFive = () => 5
const addFive = a => a + 5
const divide = (a, b) => a / b
function getFive() {
return 5
}
function addFive(a) {
return a + 5
}
function divide(a, b) {
return a / b
}
function TeddyBearList({teddyBears}) {
return (
<ul>
{teddyBears.map(teddyBear => (
<li key={teddyBear.id}>
<span>{teddyBear.name}</span>
</li>
))}
</ul>
)
}
上面的例子中值得一提的是,圓括號 ( 的閉合。這是使用 JSX 時利用箭頭函數的隱式返回能力的一種常見方法。
解構可能是我最喜歡的 JavaScript 特性之一。我經常解構對象和數組(而且如果你使用useState,你可能也會這樣喜歡這個特性)。我喜歡它強大的表達能力。
function makeCalculation({x, y: d, z = 4}) {
return Math.floor((x + d + z) / 3)
}
function makeCalculation(obj) {
const {x, y: d, z = 4} = obj
return Math.floor((x + d + z) / 3)
}
function makeCalculation(obj) {
const x = obj.x
const d = obj.y
const z = obj.z === undefined ? 4 : obj.z
return Math.floor((x + d + z) / 3)
}
function UserGitHubImg({username = 'ghost', ...props}) {
return <img src={`https://github.com/${username}.png`} {...props} />
}
MDN: Destructuring assignmenthttps://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment
一定要讀這篇 MDN 文章。你一定會學到一些新東西。當你讀完了,嘗試用解構方式的一行代碼來重構如下代碼:
function nestedArrayAndObject() {
const info = {
title: 'Once Upon a Time',
protagonist: {
name: 'Emma Swan',
enemies: [
{name: 'Regina Mills', title: 'Evil Queen'},
{name: 'Cora Mills', title: 'Queen of Hearts'},
{name: 'Peter Pan', title: `The boy who wouldn't grow up`},
{name: 'Zelena', title: 'The Wicked Witch'},
],
},
}
const title = info.title
const protagonistName = info.protagonist.name
const enemy = info.protagonist.enemies[3]
const enemyTitle = enemy.title
const enemyName = enemy.name
return `${enemyName} (${enemyTitle}) is an enemy to ${protagonistName} in "${title}"`
}
function add(a, b = 0) {
return a + b
}
const add = (a, b = 0) => a + b
function add(a, b) {
b = b === undefined ? 0 : b
return a + b
}
function useLocalStorageState({
key,
initialValue,
serialize = v => v,
deserialize = v => v,
}) {
const [state, setState] = React.useState(
() => deserialize(window.localStorage.getItem(key)) || initialValue,
)
const serializedState = serialize(state)
React.useEffect(() => {
window.localStorage.setItem(key, serializedState)
}, [key, serializedState])
return [state, setState]
}
const arr = [5, 6, 8, 4, 9]
Math.max(...arr)
Math.max.apply(null, arr)
const obj1 = {
a: 'a from obj1',
b: 'b from obj1',
c: 'c from obj1',
d: {
e: 'e from obj1',
f: 'f from obj1',
},
}
const obj2 = {
b: 'b from obj2',
c: 'c from obj2',
d: {
g: 'g from obj2',
h: 'g from obj2',
},
}
console.log({...obj1, ...obj2})
console.log(Object.assign({}, obj1, obj2))
function add(first, ...rest) {
return rest.reduce((sum, next) => sum + next, first)
}
function add() {
const first = arguments[0]
const rest = Array.from(arguments).slice(1)
return rest.reduce((sum, next) => sum + next, first)
}
function Box({className, ...restOfTheProps}) {
const defaultProps = {
className: `box ${className}`,
children: 'Empty box',
}
return <div {...defaultProps} {...restOfTheProps} />
}
export default function add(a, b) {
return a + b
}
export const foo = 'bar'
export function subtract(a, b) {
return a - b
}
export const now = new Date()
import React, {Suspense, Fragment} from 'react'
我對這個語法進行了全面的講解,你可以在此觀看:https://www.youtube.com/watch?v=kTlcu16rSLc&list=PLV5CVI1eNcJgNqzNwcs4UKrlJdhfDjshf。
我喜歡三元條件表達式,因為它們的聲明方式太美了,特別是在 JSX 中。onst message = bottle.fullOfSoda
? 'The bottle has soda!'
: 'The bottle may not have soda :-('
let message
if (bottle.fullOfSoda) {
message = 'The bottle has soda!'
} else {
message = 'The bottle may not have soda :-('
}
function TeddyBearList({teddyBears}) {
return (
<React.Fragment>
{teddyBears.length ? (
<ul>
{teddyBears.map(teddyBear => (
<li key={teddyBear.id}>
<span>{teddyBear.name}</span>
</li>
))}
</ul>
) : (
<div>There are no teddy bears. The sadness.</div>
)}
</React.Fragment>
)
}
我知道三元條件表達式會受到一些人的反感,他們不得不忍受在 prettier 清理我們的代碼之前理解三元條件表達式。如果你還沒有使用 prettier,我強烈建議你使用。Prettier 會讓你的三元條件表達式更易讀。
數組太棒了,我一直使用數組方法!我可能會經常使用如下方法:reduce
const dogs = [
{
id: 'dog-1',
name: 'Poodle',
temperament: [
'Intelligent',
'Active',
'Alert',
'Faithful',
'Trainable',
'Instinctual',
],
},
{
id: 'dog-2',
name: 'Bernese Mountain Dog',
temperament: ['Affectionate', 'Intelligent', 'Loyal', 'Faithful'],
},
{
id: 'dog-3',
name: 'Labrador Retriever',
temperament: [
'Intelligent',
'Even Tempered',
'Kind',
'Agile',
'Outgoing',
'Trusting',
'Gentle',
],
},
]
dogs.find(dog => dog.name === 'Bernese Mountain Dog')
dogs.some(dog => dog.temperament.includes('Aggressive'))
dogs.some(dog => dog.temperament.includes('Trusting'))
dogs.every(dog => dog.temperament.includes('Trusting'))
dogs.every(dog => dog.temperament.includes('Intelligent'))
dogs.map(dog => dog.name)
dogs.filter(dog => dog.temperament.includes('Faithful'))
dogs.reduce((allTemperaments, dog) => {
return [...allTemperaments, ...dog.temperaments]
}, [])
function RepositoryList({repositories, owner}) {
return (
<ul>
{repositories
.filter(repo => repo.owner === owner)
.map(repo => (
<li key={repo.id}>{repo.name}</li>
))}
</ul>
)
}
這是一個很大的主題,它可能需要花費一些時間練習和使用它們才能用好它們。Promises 在 JavaScript 生態系統中無處不在,而且由於 React 在這個系統中的牢固地位,因此 Promises 在 React 中也無處不在(事實上,React 內部本身也使用 promises)。
Promises 幫你處理異步代碼,並從許多 DOM API 和第三方庫中解脫出來。Async/await 是處理 promises 的一種特殊語法。這兩者相輔相成。function promises() {
const successfulPromise = timeout(100).then(result => `success: ${result}`)
const failingPromise = timeout(200, true).then(null, error =>
Promise.reject(`failure: ${error}`),
)
const recoveredPromise = timeout(300, true).then(null, error =>
Promise.resolve(`failed and recovered: ${error}`),
)
successfulPromise.then(log, logError)
failingPromise.then(log, logError)
recoveredPromise.then(log, logError)
}
function asyncAwaits() {
async function successfulAsyncAwait() {
const result = await timeout(100)
return `success: ${result}`
}
async function failedAsyncAwait() {
const result = await timeout(200, true)
return `failed: ${result}`
}
async function recoveredAsyncAwait() {
let result
try {
result = await timeout(300, true)
return `failed: ${result}`
} catch (error) {
return `failed and recovered: ${error}`
}
}
successfulAsyncAwait().then(log, logError)
failedAsyncAwait().then(log, logError)
recoveredAsyncAwait().then(log, logError)
}
function log(...args) {
console.log(...args)
}
function logError(...args) {
console.error(...args)
}
function timeout(duration = 0, shouldReject = false) {
return new Promise((resolve, reject) => {
setTimeout(() => {
if (shouldReject) {
reject(`rejected after ${duration}ms`)
} else {
resolve(`resolved after ${duration}ms`)
}
}, duration)
})
}
function GetGreetingForSubject({subject}) {
const [isLoading, setIsLoading] = React.useState(false)
const [error, setError] = React.useState(null)
const [greeting, setGreeting] = React.useState(null)
React.useEffect(() => {
async function fetchGreeting() {
try {
const response = await window.fetch('https://example.com/api/greeting')
const data = await response.json()
setGreeting(data.greeting)
} catch (error) {
setError(error)
} finally {
setIsLoading(false)
}
}
setIsLoading(true)
fetchGreeting()
}, [])
return isLoading ? (
'loading...'
) : error ? (
'ERROR!'
) : greeting ? (
<div>
{greeting} {subject}
</div>
) : null
}
在構建 React 應用程式時,當然還有許多有用的語言特性,但是這些是我最喜歡並且自己一直重複使用的一些特性。我希望這些對你也有用。
如果你希望深入了解這些特性,我有一個我在 PayPal 工作時主持和記錄的 JavaScript 研討會,可能會對你有所幫助:https://www.youtube.com/playlist?list=PLV5CVI1eNcJgUA2ziIML3-7sMbS7utie5
英文原文:https://kentcdodds.com/blog/javascript-to-know-for-react