编写更好的React代码的小技巧(附实例)

99 阅读7分钟

编写更好的React代码的小技巧

今天我们来谈谈我最喜欢的一些小技巧,这些小技巧超级容易实现或遵循,可以让你的JavaScript代码更简洁。另外,请记住,我们今天要学习的一些东西适用于一般的JavaScript,尽管文章的重点是React。


对象重构

为了开始,我们将回顾一下对象重构,实际上这是我最喜欢的方法之一,它可以帮助保持代码的小、干净和优雅。我非常喜欢这个话题,实际上我在这里做了一整篇关于它的文章。通过使用JavaScript去结构化写出更干净的代码。解构允许你将复杂的结构分解成更简单的部分。让我们来看看一个例子:

const { title } = props
console.log(title);

React开发者使用这种技术的一个常见地方是道具。尽管有些人可能会说,当你分割变量时,你会失去上下文,但在React中通常是这样的,上下文是由组件本身继承的。让我们看一个例子来说明我的意思。

首先,让我们写一个简单的组件,在屏幕上显示任务信息:

function TaskView(props) {
    return (
        <h1>{props.task.title}</h1>
        <p>{props.task.description}</p>
        <span>{props.task.completed ? 'Completed' : 'Pending'}</span>
    )
}

这确实很简单,但是,看看我们是如何一直重复道具的,不是很好看。让我们看看另一种方法来实现它:

function TaskView(props) {
    const task = props.task
    return (
        <h1>{task.title}</h1>
        <p>{task.description}</p>
        <span>{task.completed ? 'Completed' : 'Pending'}</span>
    )
}

这有点好,但仍然是我们到处都有任务。现在,那些不了解结构化的人可能会想做这样的事情:

const title = props.task.title
const description = props.task.description

这给声明增加了太多的开销。现在让我们看看这个组件在使用析构的时候是什么样子的:

function TaskView(props) {
    const { title, description, completed } = props.task
    return (
        <h1>{title}</h1>
        <p>{description}</p>
        <span>{completed ? 'Completed' : 'Pending'}</span>
    )
}

现在代码非常简单,我们把JSX和其他部分保持得非常干净,而且我们还在上下文中。完全可以理解,当我们说title ,我们是在谈论Task ,因为这是组件的全部内容。因此,保持你的名字干净,并很好地结构你的组件,你会喜欢这个功能。


简化你的条件语句

在这一节中,我想谈谈3种不同的情况,它们可以帮助我们提高代码的可读性,而且这很容易,尽管很多时候我们会忘记这样做。

条件性执行

在某些时候,我们需要在某个条件恰好为真时才运行一个语句,这很正常。通常情况下,它是这样的:

const isFive = (num) => num === 5
if (isFive(5)) {
    console.log('It is the number five!')
}

现在,这段代码本身并没有什么问题,然而,它可以被简化一下:

const isFive = (num) => num === 5
isFive(5) && console.log('It is the number five!')

不错,但它是如何工作的呢?JavaScript和其他许多语言一样,从左到右依次读取条件语句,比如我们的&&|| ,它们在可以使参数无效的时候退出。

让我们看一个所有条件语句的例子:

const t = 1
t === 1 && t === 2 && t === 3

在该例子中,JS将首先取第一个表达式t === 1 ,因为该表达式是真性的,而且我们有一个and 条件,它需要评估下一个表达式,因为我们需要保证它们都是真性的。当它评估t === 2 ,这是虚假的,它根本不需要评估t === 3 ,它可以保存这个计算,因为我们知道整个语句刚好是false

令人惊讶!现在让我们再来了解一下这方面的情况。在互联网上很常见到这样的例子,然而,你知道你也可以使用|| 操作符吗?

const isFive = (num) => num === 5
isFive(5) || console.log('It is the number five!') // does not execute the console.log
isFive(10) || console.log('It is not the number five!') // it executes the console.log

你是否注意到,我们刚才所做的相当于对我们的第一个例子应用了一个not?

const isFive = (num) => num === 5
isFive(5) && console.log('It is the number five!') // it executes the console.log
!isFive(10) && console.log('It is not the number five!') // it executes the console.log

三元运算符

条件(三元)运算符是唯一一个需要三个操作数的JavaScript运算符:一个条件,后面是一个问号(?),然后是一个表达式,如果条件是真实的,后面是一个冒号(:),最后是表达式,如果条件是虚假的,就要执行。

这非常常用于根据条件语句向用户显示不同的状态或组件。虽然我并不总是推荐使用三元运算符,但有时一个好的老式if就能很好地完成工作。它对小事情非常有用。

请看下面的例子:

if (completed) {
    return 'Completed'
} else {
    return 'Pending'
}

另一个变体,我仍然看到它的存在:

if (completed) { return 'Completed'} else { return 'Pending' }

我不是来评判的,但这可能会变得非常混乱。让我们来看看使用三元运算符的方法。

return completed ? 'Completed' : 'Pending'

好多了!

可选链式

最后但并非最不重要的是,我们有可选链(?. ),它允许读取位于连接对象链深处的一个属性的值,而不必明确验证每个引用。

通俗地说,它有助于避免一堆if 语句,以确保我们在一个嵌套的属性上有一个值。让我们看一个例子:

const juan = {
    name: 'Juan',
    marriedTo: {
        name: 'Diana'
    }
}

console.log(juan.marriedTo.name) // Diana
console.log(juan.divorcedFrom.name) // Cannot read property 'name' of undefined

Ups....,当我们试图访问我们正在离婚的人的名字时,我们得到了一个错误,因为在我们的案例中divorcedFrom ,是未定义的。通常情况下,我们会像这样解决:

if (juan.divorcedFrom) {
    console.log(juan.divorcedFrom.name)
}

但这也会因为添加大量的ifs而失去控制。有一个更好的方法,就是使用可选链:

const juan = {
    name: 'Juan',
    marriedTo: {
        name: 'Diana'
    }
}

console.log(juan.marriedTo?.name) // Diana
console.log(juan.divorcedFrom?.name) // undefined

而且这可以适用于多个层次

juan.marriedTo?.disvorcedFrom?.kids

非常好!让我们继续下一个话题


传播操作符

没有一个React应用不使用传播操作符,也许这很夸张,但传播操作符在React应用中被广泛使用,特别是在使用减速器时,尽管它不仅仅是为了这个。这也是我在《如何在JavaScript中使用扩散操作符(...)》一文中广泛涉及的另一个话题。我非常推荐你阅读这篇文章,它非常酷,而且详细地涵盖了这个话题。

展开操作符允许你将一个可迭代对象扩展为一个单独的元素列表。让我们最好看一下一些例子:

function sum(x, y, z) {
  return x + y + z
}

const numbers = [1, 2, 3]

console.log(sum(...numbers)) // 6

在这种情况下,我们要做的是将一个array 转化为单独的变量,并传递给我们的sum 函数。这是一个相当巧妙的技巧。但是我们也可以把它应用于对象:

const obj1 = { foo: 'bar', x: 42 }
const obj2 = { foo: 'baz', y: 13 }

const copyObj1 = { ...obj1 } // This copies all the properties of obj1 into a new object.

const merged = { ...obj1, ...obj2 } // This merges all the properties of obj1 and obj2 into a new object.

console.log(merged) // {foo: "baz", x: 42, y: 13}

因为我们可以用它来创建新的对象或数组,它非常适合与Redux一起使用,因为我们可以避免突变原始对象。


模板字样

虽然非常流行,对初学者也很友好,但如果没有它们,任何列表都是不完整的。模板字样基本上是字符串,但不是任何字符串,它们允许嵌入表达式。让我们看一下:

console.log(`this is a string literal`)

在其更基本的形式中,字符串字头只是一个字符串,然而,请注意,要成为一个字符串字头,它必须使用` ,而不是"' 。这是一个小细节,但有很大的区别。

例如,字符串字面符号支持多行字符串:

console.log(`line 1
line 2`)

或者你也可以嵌入表达式

const a = 10
const b = 25

console.log(`a: ${a} and b: ${b} but more importantly a+b = ${a+b}`) // a: 10 and b: 25 but more importantly a+b = 35

真的很酷


总结

JavaScript有很多有用的运算符、表达式和技巧,可以增强我们的开发能力,写出更干净的代码。我提到的一些东西也确实是个人的判断,但如果你看一下非常受欢迎的项目上写的React代码,你会发现他们到处都在应用这些小东西。因此,当你写下一个React组件时,它们真的很值得学习和实施。

谢谢你的阅读