使用 React 要懂的 Js特性

react

与我使用的其他框架相比,我最喜欢 react 的原因之一就是它对 JavaScript 的暴露程度。没有模板DSL( jsX 编译为合理的 JavaScript),组件 API 只是通过添加 React Hooks 变得更简单,并且该框架为解决的核心 UI 问题提供非常少的抽象概念。

因此,学习 JavaScript 对于使用 react 有效构建应用程序是非常可取的。所以这里有一些 JavaScript 功能,我建议你花一些时间学习,这样你就可以尽可能有效地使用 React。

模板文字

模板文字就像具有超能力的字符串:

const greeting = 'Hello'

const subject = 'World'

console.log(`${greeting} ${subject}!`) // Hello World!

// this is the same as:

console.log(greeting + ' ' + subject + '!')

// in React:

function Box({className, ...props}) {

return <div className={`box ${className}`} {...props} />

}

MDN: 模板文字

简写属性名

很常见并且有用,我直到现在都没有想到可以这样做。

const a = 'hello'

const b = 42

const c = {d: [true, false]}

console.log({a, b, c})

// this is the same as:

console.log({a: a, b: b, c: c})

// in React:

function Counter({initialCount, step}) {

const [count, setCount] = useCounter({initialCount, step})

return <button onClick={setCount}>{count}</button>

}

MDN: ECMAScript 2015中对象初始化的新表示法

箭头函数

箭头函数是在 JavaScript 中另一种编写函数的方法,但它们确实存在一些语义差异。幸运的是我们在 React 的土地上,如果在项目中使用hook(而不是类)就不必担心 this,但是箭头函数允许更复杂的匿名函数和隐式返回,所以你会看到并想要充分利用箭头的功能。

const getFive = () => 5

const addFive = a => a + 5

const divide = (a, b) => a / b

// this is the same as:

function getFive() {

return 5

}

function addFive(a) {

return a + 5

}

function divide(a, b) {

return a / b

}

// in React:

function TeddyBearList({teddyBears}) {

return (

<ul>

{teddyBears.map(teddyBear => (

<li key={teddyBear.id}>

<span>{teddyBear.name}</span>

</li>

))}

</ul>

)

}

MDN: 箭头函数

解构

解构可能是我最喜欢的 JavaScript 功能。我一直在构造对象和数组(如果你使用 useState,可能也是如此,就像这样)。我喜欢它的陈述性。

// const obj = {x: 3.6, y: 7.8}

// makeCalculation(obj)

function makeCalculation({x, y: d, z = 4}) {

return Math.floor((x + d + z) / 3)

}

/ this is the same as

function makeCalculation(obj) {

const {x, y: d, z = 4} = obj

return Math.floor((x + d + z) / 3)

}

// which is the same as

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)

}

// in React:

function UserGitHubImg({username = 'ghost', ...props}) {

return <img src={`https://github.com/${username}.png`} {...props} />

}

MDN: 解构分配

一等要去阅读 MDN 文章,你肯定能够学到新东西。当你完成后,尝试用单行解构:

function nestedArrayAndObject() {

// refactor this to a single line of destructuring...

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 {} = info // <-- replace the next few `const` lines with this

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}"`

}

参数默认值

这是另一个我一直在用的功能:一种以声明方式表达函数默认值的非常强大的方法。

// add(1)

// add(1, 2)

function add(a, b = 0) {

return a + b

}

// is the same as

const add = (a, b = 0) => a + b

// is the same as

function add(a, b) {

b = b === undefined ? 0 : b

return a + b

}

// in React:

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]

}

MDN: 默认参数

Rest/Spread

...语法可以被认为是一种“集合”语法,它在一组值上运行。我一直都在使用,强烈建议你也学习。它实际上在不同的环境中有不同的含义,因此学习那些细微差别会对你有所帮助。

const arr = [5, 6, 8, 4, 9]

Math.max(...arr)

// is the same as

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})

// is the same as

console.log(Object.assign({}, obj1, obj2))

function add(first, ...rest) {

return rest.reduce((sum, next) => sum + next, first)

}

// is the same as

function add() {

const first = arguments[0]

const rest = Array.from(arguments).slice(1)

return rest.reduce((sum, next) => sum + next, first)

}

// in React:

function Box({className, ...restOfTheProps}) {

const defaultProps = {

className: `box ${className}`,

children: 'Empty box',

}

return <div {...defaultProps} {...restOfTheProps} />

}

MDN: Spread语法

MDN: Rest 参数

ESModules

如果你正在使用现代工具构建自己的程序,它应该能够支持模块,了解语法怎样工作是个好主意,因为所有的甚至微不足道的程序都可能需要使用模块来重用代码。

export default function add(a, b) {

return a + b

}

/*

* import add from './add'

* console.assert(add(3, 2) === 5)

*/

export const foo = 'bar'

/*

* import {foo} from './foo'

* console.assert(foo === 'bar')

*/

export function subtract(a, b) {

return a - b

}

export const now = new Date()

/*

* import {subtract, now} from './stuff'

* console.assert(subtract(4, 2) === 2)

* console.assert(now instanceof Date)

*/

// in React:

import React, {Suspense, Fragment} from 'react'

MDN: import

MDN: export

三元表达式

我喜欢三元表达式。他们的声明很漂亮。特别是在 jsX 中。

const message = bottle.fullOfSoda

? 'The bottle has soda!'

: 'The bottle may not have soda :-('

// is the same as

let message

if (bottle.fullOfSoda) {

message = 'The bottle has soda!'

} else {

message = 'The bottle may not have soda :-('

}

// in React:

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 将使你的三元表达式更容易阅读。

MDN: 条件(三元)运算符

数组方法

数组很棒,我一直使用数组方法!以下是我常用的方法:

  • find
  • some
  • every
  • includes
  • map
  • filter
  • 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')

// {id: 'dog-2', name: 'Bernese Mountain Dog', ...etc}

dogs.some(dog => dog.temperament.includes('Aggressive'))

// false

dogs.some(dog => dog.temperament.includes('Trusting'))

// true

dogs.every(dog => dog.temperament.includes('Trusting'))

// false

dogs.every(dog => dog.temperament.includes('Intelligent'))

// true

dogs.map(dog => dog.name)

// ['Poodle', 'Bernese Mountain Dog', 'Labrador Retriever']

dogs.filter(dog => dog.temperament.includes('Faithful'))

// [{id: 'dog-1', ..etc}, {id: 'dog-2', ...etc}]

dogs.reduce((allTemperaments, dog) => {

return [...allTemperaments, ...dog.temperaments]

}, [])

// [ 'Intelligent', 'Active', 'Alert', ...etc ]

// in React:

function RepositoryList({repositories, owner}) {

return (

<ul>

{repositories

.filter(repo => repo.owner === owner)

.map(repo => (

<li key={repo.id}>{repo.name}</li>

))}

</ul>

)

}

MDN: Array

广州品牌设计公司https://www.houdianzi.com PPT模板下载大全https://redbox.wode007.com

Promises 和 async/await

这是一个很大的主题,可以在它们身上多花一些时间。Promises 在 JavaScript 生态中无处不在,并且由于 React在该生态系统中的根深蒂固,它们几乎到处都是(事实上,React 本身在内部也在使用 promises)。

Promises 可帮助你管理异步代码。 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}` // this would not be executed

} 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)

}

// This is the mothership of all things asynchronous

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)

})

}

// in React:

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 要懂的 Js特性 的全部内容, 来源链接: utcz.com/z/383267.html

回到顶部