编写更好的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组件时,它们真的很值得学习和实施。
谢谢你的阅读