为了保证可读性,本文采用意译而非直译。另外,本文版权归原作者所有,翻译仅用于学习。转载请联系作者。
两周前,我开始做一个新项目,有些代码已经写好了。然而,没有最佳实践可遵循。当你开始做一个新项目时,重要的是一起定义基础和最佳实践/指南,团队将遵循此基础来编写最佳代码:可维护,易读,易于理解。
我将描述我在项目中看到的5种情况以及如何改进它们。
关键字:一致性
1.导入模块的顺序
以有组织的方式引入ES6模块将节省你查找任何找不到或不需要模块的时间。
之前
import { DatePicker } from '../../components'
import axios from 'axios'
import { IUser } from '../../models/User'
import React from 'react'
import { toCamelCase } from '../utils'
import { Button } from '@material-ui/core'之后
// node_modules
import React from 'react'
import { Button } from '@material-ui/core'
import axios from 'axios'
// Local modules
import { DatePicker } from '../../components'
import { toCamelCase } from '../utils'
// Types + Interfaces
import { IUser } from '../../models/User'在之前的引入是无序的,一个文件可能不会太乱,但是当你打开大量文件时候,尝试找到一个特定的包真的很难。我们团队达成一致,使用之后一种方式对导入的包进行分组,通过空格行分割每个模块。因为文件将保持一致,就可以删除注释了。
2.尽可能使用解构
另外一个重要的事情就是防止不必要的嵌套和重复。在大多数情况下,将大大提升可读性。
之前
const UserProfile = props => (<div>
<span>{props.firstName}</span>
<span>{props.lastName}</span>
<img src={props.profilePhoto}/>
</div>)之后
const UserProfile = ({ firstName, lastName, profilePhoto }) =>
(<div>
<span>{firstName}</span>
<span>{lastName}</span>
<img src={profilePhoto}/>
</div>)3.变量和方法的命名约定
关于代码,有一点很重要,就是要知道一个方法将返回什么,或者通过变量名轻松理解变量的含义(变量语义化),比如
之前
let User = {}
User.car = true
User.admin = true
function NewUser() {
return User
}
function add_photo(photo) {
user.photo = photo
}
之后
let user = {}
user.hasCar = true
user.isAdmin = true
function getUser() {
return user
}
function setUserPhoto(photoUrl) {
user.photoUrl = photoUrl
}在之后展示了如何在命名变量和方法保持一致性,在以下方面保持一致:
- 对于布尔类型使用:is, has,should做前缀
- 对于方法使用 get/set 做前缀如果是操作 props
- 变量和方法都使用驼峰命名
4.为你的组件接收公共变量做好准备
之前
const UserProfile = props => {
const { firstName, lastName, profilePhoto } = props
return (<div>
<span>{firstName}</span>
<span>{lastName}</span>
<img src={profilePhoto}/>
</div>)
}之后
const UserProfile = props => {
const { firstName, lastName, profilePhoto, ...rest} = props
return (<div {...rest}>
<span>{firstName}</span>
<span>{lastName}</span>
<img src={profilePhoto}/>
</div>)
}5.哑组件(dumb components)让开发更简单
之前
import axios from 'axios'
const UserProfile = props => {
const [user, setUser] = React.useState(null);
React.useEffect(() => {
getUser();
}, []);
async function getUser() {
try {
const user = await axios.get('/user/25')
} catch(error) {
console.error(error)
}
if(user.country === "DE") {
user.flag = "/de-flag.png"
} else if(user.country === "MX") {
user.flag = "/mx-flag.png"
}
setUser(user);
}
const { firstName, lastName, profilePhoto, userFlag} = user
return (<div>
<span>{firstName}</span>
<span>{lastName}</span>
<img src={profilePhoto}/>
<img src={userFlag}>
</div>)
}哪些可能会导致问题?
在组件里添加业务逻辑( Business Logic )会让它变得很难维护,调试和测试。我的建议是让你的组件作为展示组件(presentational component)。这样,你可以独立出业务逻辑,然后专注于独立地测试该组件。前面的每个逻辑都混在一起。现在我们把每个职责分开,这样更容易测试和调试。
// UserProfilePage.jsx
// 操作所有的UserProfilePage相关,添加任何额外的props或业务逻辑
import { fetchUser } from '../api'
const UserProfilePage = props => {
const [user, setUser] = React.useState(null);
React.useEffect(() => {
getUser();
}, []);
async function getUser() {
const user = fetchUser(error => console.error(error))
if(user.country === "DE") {
user.flag = "/de-flag.png"
} else if(user.country === "MX") {
user.flag = "/mx-flag.png"
}
setUser(user);
}
return <UserProfile {...user}/>
}
// API.js
// 获取数据并处理错误
export const fetchUser = async (errorHandler) => {
try {
const user = await axios.get('/user/25')
retrun user
} catch(error) {
errorHandler(error)
}
}
// UserProfile.jsx
// UserProfile.jsx如下
const UserProfile = props => {
const { firstName, lastName, profilePhoto, ...rest} = props
return (<div {...rest}>
<span>{firstName}</span>
<span>{lastName}</span>
<img src={profilePhoto}/>
</div>)
}
附加:如果你正在使用类型检查器,请让它发挥作用。
如果你的团队选择使用类型检查器,那么使用严格模式很重要,以确保它能发挥作用,来达到使用它的目的。
之前
const UserProfile = (props: any) => {
const { firstName, lastName, profilePhoto, shouldShowPhoto } = props
return (<div>
<span>{firstName}</span>
<span>{lastName}</span>
<img src={profilePhoto}/>
</div>)
}之后
interface IUserProfile {
firstName: string
lastName: string
profilePhoto: string
shouldShowPhoto?: boolean
}
const UserProfile = (props: IUserProfile) => {
const { firstName, lastName, profilePhoto, shouldShowPhoto } = props
return (<div>
<span>{firstName}</span>
<span>{lastName}</span>
{shouldShowPhoto && <img src={profilePhoto}/>}
</div>)
}我并不是说这些规则适用于所有项目,但你的团队需要制定自己的并且达成统一。
你有哪些最佳实践/指南?
关于我
获取更多技术相关文章,关注公众号”前端女塾“。
回复加群,即可加入”前端仙女群“
您也可以扫描添加下方的微信并备注 Sol 加前端交流群,交流学习。