原文: 21 Best Practices for a Clean React Project
工程实践是经验的累计,长久以来自己在项目中学习、思考,形成一套 React 的实践思维,但是它一直在我脑子里,直到我看到这篇优秀的文章,让我觉得,这种思维可以被记录下来。接下来结合个人理解,给大家介绍这篇文章。
- 以下代码都是对的,只是写法有区分,更多的是介绍学习一种编码思维。
JSX boolean 类型属性简写
当属性是 boolean 类型时,直接添加,JSX 会默认解析 props: { disabled: true }
Bad
const Demo = () => {
return (<Button disabled={true} hide={false}>Demo</Button>);
}
✨Good
const Demo = () => {
return (<Button disabled hide={false}>Demo</Button>);
}
合理运用三元运算符
其实跟 canShow ? <div>Demo</div> : null 有异曲同工,这里强调的是代码一致性。
Bad
const { role } = user;
if(role === ADMIN) {
return <AdminUser />
}else{
return <NormalUser />
}
✨Good
const { role } = user;
return role === ADMIN ? <AdminUser /> : <NormalUser />
利用对象替换 switch
这种主要还是看团队的约定,不同团队对 switch 的看法不一样。
Bad
const {role} = user
switch(role){
case ADMIN:
return <AdminUser />
case EMPLOYEE:
return <EmployeeUser />
case USER:
return <NormalUser />
}
Good
const {role} = user
const components = {
ADMIN: AdminUser,
EMPLOYEE: EmployeeUser,
USER: NormalUser
};
const Component = components[role];
return <Componenent />;
利用 Fragments
学会利用 React.Fragments,这样可以将减少额外的虚拟节点,还能让代码更简洁,并且具有层级结构更加易读。
Bad
return (
<div>
<Component1 />
<Component2 />
<Component3 />
</div>
)
return [
<Component1 />,
<Component2 />,
<Component3 />
];
✨Good
return (
<>
<Component1 />
<Component2 />
<Component3 />
</>
)
不要在绑定组件事件时,使用匿名函数
当扫描虚拟树时,匿名函数会重复创建,造成额外的内存占用。
Bad
return (
<button onClick={() => dispatch(ACTION_TO_SEND_DATA)}> // NOTICE HERE
This is a bad example
</button>
)
✨Good
const submitData = () => dispatch(ACTION_TO_SEND_DATA)
return (
<button onClick={submitData}>
This is a good example
</button>
)
使用 memo
这里涉及的比较多,可以自己去了解。这里就不展开讨论,React 的 memo 一般都用 React.PureComponent 和 React.memo 。
合理利用解构赋值
这种有点偏函数式编程的理念,因为 state 和 props 都是禁止直接赋值,所以在使用 state 和 props 时,更多是以常量的形式使用,恰好满足函数式编程理念中变量提升的规范。在顶部的解构,可以让开发人员不必详细的阅读代码,也能快速知道变量的使用,后续拓展修改变量,也可以快速覆盖,降低遗漏风险。
Bad
return (
<>
<div> {user.name} </div>
<div> {user.age} </div>
<div> {user.profession} </div>
</>
)
✨Good
const { name, age, profession } = user;
return (
<>
<div> {name} </div>
<div> {age} </div>
<div> {profession} </div>
</>
)
属性为静态字符串时
文本属于静态属性,没必要加多一层括号,不易阅读。
Bad
return(
<Navbar title={"My Special App"} />
)
✨Good
return(
<Navbar title="My Special App" />
)
将非视图相关的 JS 逻辑代码从 JSX 中移出
在 JSX 中写逻辑代码,会阻塞 JSX 解析。
Bad
return (
<ul>
{posts.map((post) => (
<li onClick={event => {
console.log(event.target, 'clicked!'); // <- THIS IS BAD
}} key={post.id}>{post.title}
</li>
))}
</ul>
);
✨Good
const onClickHandler = (event) => {
console.log(event.target, 'clicked!');
}
return (
<ul>
{posts.map((post) => (
<li onClick={onClickHandler} key={post.id}> {post.title} </li>
))}
</ul>
);
合理使用模板字符串
Bad
const userDetails = user.name + "'s profession is" + user.proffession
return (
<div> {userDetails} </div>
)
✨Good
这样非常简洁易读,看着心情就舒服些。
const userDetails = `${user.name}'s profession is ${user.proffession}`
return (
<div> {userDetails} </div>
)
引用分类
Bad
import React from 'react';
import ErrorImg from '../../assets/images/error.png';
import styled from 'styled-components/native';
import colors from '../../styles/colors';
import { PropTypes } from 'prop-types';
✨Good
推荐分类规则:
- 构建相关
- 第三方库、公共库
- 项目内的引用
方便自己和其他人快速定位模块和识别模块风险。
import React from 'react';
import { PropTypes } from 'prop-types';
import styled from 'styled-components/native';
import ErrorImg from '../../assets/images/error.png';
import colors from '../../styles/colors';
React 组件命名
采用首字母小写来命名实例化组件,避免模块命名冲突,降低引用的识别风险。
Bad
import reservationCard from './ReservationCard';
const ReservationItem = <ReservationCard />;
✨Good
import ReservationCard from './ReservationCard';
const reservationItem = <ReservationCard />;
属性引号
JSX 的属性使用双引号,其他 JS 的使用单引号,大部分项目中,都会利用自动化工具进行格式化校验。
Bad
<Foo bar='bar' />
<Foo style={{ left: "20px" }} />
✨Good
<Foo bar="bar" />
<Foo style={{ left: '20px' }} />
Props 的命名规范
使用小驼峰命名自定义的 props,跟官方的 onClick 保持一致性。
Bad
<Component
UserName="hello"
phone_number={12345678}
/>
✨Good
<MyComponent
userName="hello"
phoneNumber={12345678}
/>
JSX 的代码风格
大于一行的 JSX 代码,可以使用括号包裹,进行格式化后,JSX 具有易读的层级缩进。
Bad
看着难受
return <MyComponent variant="long">
<MyChild />
</MyComponent>;
✨Good
舒舒服服
return (
<MyComponent variant="long">
<MyChild />
</MyComponent>
);
闭合单标签
当标签内没有内容时,闭合单标签,通过这样标识的标签更易读。
Bad
<SomeComponent variant="stuff"></SomeComponent>
✨Good
<SomeComponent variant="stuff" />
结尾
试着将它们运用到项目中,让你的代码更易读、更纯粹。