清洁React项目的21个最佳实践

React 对于如何构建事物非常没有主见。这正是我们有责任保持项目整洁和可维护的原因。

今天,我们将讨论一些改善 React 应用程序健康状况的最佳实践。这些规则被广泛接受。因此,掌握这些知识是势在必行的。

一切都将通过代码进行演示,所以请系好安全带!

1. 使用JSX简写

尝试使用 JSX 简写来传递布尔变量。假设您想要控制导航栏组件的标题可见性。

bad

1
2
3
return (
<Navbar showTitle={true} />
);

good

1
2
3
return(
<Navbar showTitle />
)

2. 使用三元运算符

假设您想根据角色显示用户的详细信息。

bad

1
2
3
4
5
6
7
const { role } = user;

if(role === ADMIN) {
return <AdminUser />
}else{
return <NormalUser />
}

goods

1
2
3
const { role } = user;

return role === ADMIN ? <AdminUser /> : <NormalUser />

3. 利用对象字面量

对象字面量可以帮助我们的代码更具可读性。假设您想根据角色显示三种类型的用户。您不能使用三元,因为选项数量超过两个。

bad

1
2
3
4
5
6
7
8
9
10
const {role} = user

switch(role){
case ADMIN:
return <AdminUser />
case EMPLOYEE:
return <EmployeeUser />
case USER:
return <NormalUser />
}

good

1
2
3
4
5
6
7
8
9
10
11
const {role} = user

const components = {
ADMIN: AdminUser,
EMPLOYEE: EmployeeUser,
USER: NormalUser
};

const Component = components[role];

return <Componenent />;

现在看起来好多了。

4. 使用片段

尽量使用Fragment而不是div. 它可以保持代码整洁,并且也有利于性能,因为在虚拟 DOM 中创建的节点少了一个。

bad

1
2
3
4
5
6
7
return (
<section>
<Component1 />
<Component2 />
<Component3 />
</section>
);

good

1
2
3
4
5
6
7
return (
<>
<Component1 />
<Component2 />
<Component3 />
</>
);

5. 不要在render中定义函数

不要在render中定义函数。尽量使render中的逻辑最小化。

bad

1
2
3
4
5
return (
<button onClick={() => dispatch(ACTION_TO_SEND_DATA)}> // NOTICE HERE
This is a bad example
</button>
)

good

1
2
3
4
5
6
7
const submitData = () => dispatch(ACTION_TO_SEND_DATA)

return (
<button onClick={submitData}>
This is a good example
</button>
)

6. 使用useMemo

React.PureComponentuseMemo 可以显著提高应用程序的性能。它们帮助我们避免不必要的渲染。

bad

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import React, { useState } from "react";

export const TestMemo = () => {
const [userName, setUserName] = useState("faisal");
const [count, setCount] = useState(0);

const increment = () => setCount((count) => count + 1);

return (
<>
<ChildrenComponent userName={userName} />
<button onClick={increment}> Increment </button>
</>
);
};

const ChildrenComponent =({ userName }) => {
console.log("rendered", userName);
return <div> {userName} </div>;
};

尽管 ChildComponent 的值与 count 无关,但它应该只渲染一次。但是,每次点击按钮时它都会重新渲染。

good

ChildrenComponent 改为:

1
2
3
4
5
6
import React ,{useState} from "react";

const ChildrenComponent = React.memo(({userName}) => {
console.log('rendered')
return <div> {userName}</div>
})

现在,无论单击按钮多少次,它都只会在必要时重新渲染。

7. 使用对象解构

充分利用对象解构。假设你需要显示一个用户的详细信息。

bad

1
2
3
4
5
6
7
return (
<>
<div> {user.name} </div>
<div> {user.age} </div>
<div> {user.profession} </div>
</>
)

good

1
2
3
4
5
6
7
8
9
const { name, age, profession } = user;

return (
<>
<div> {name} </div>
<div> {age} </div>
<div> {profession} </div>
</>
)

8. 字符串类型的props不需要花括号

当向子组件传递字符串类型的props时。

bad

1
2
3
return (
<Navbar title={"My Special App"} />
)

good

1
2
3
4

return (
<Navbar title="My Special App" />
);

9. 从JSX中提取JS代码

如果JS代码没有渲染或UI功能目的,请将其从JSX中提取出来。

bad

1
2
3
4
5
6
7
8
9
10
11
12
13
14
return (
<ul>
{posts.map(post => (
<li
onClick={event => {
console.log(event.target, 'clicked!'); // <- 不好的
}}
key={post.id}
>
{post.title}
</li>
))}
</ul>
);

good

1
2
3
4
5
6
7
8
9
10
11
12
13
const onClickHandler = event => {
console.log(event.target, 'clicked!');
};

return (
<ul>
{posts.map(post => (
<li onClick={onClickHandler} key={post.id}>
{post.title}
</li>
))}
</ul>
);

10. 使用模板字符串

使用模板字符串构建大型字符串。避免使用字符串连接。它很漂亮,也很简洁。

bad

1
2
3
4
5
const userDetails = user.name + "'s profession is" + user.profession;

return (
<section>{userDetails}</section>
);

good

1
2
3
4
5
const userDetails = `${user.name}'s profession is ${user.profession}`;

return (
<section>{userDetails}</section>
);

11. 按顺序导入

尽量按一定顺序导入东西。这提高了代码的可读性。

bad

1
2
3
4
5
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

一个经验法则是保持导入顺序如下:

  • 内置的
  • 外部的
  • 内部的

所以上面的例子变为:

1
2
3
4
5
6
7
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';

12. 使用隐式返回

在编写漂亮的代码时,使用 JavaScript 的隐式return特性。假设你的函数进行一个简单的计算并返回结果。

bad

1
2
3
const add = (a, b) => {
return a + b;
};

good

1
const add = (a, b) => a + b;

13. 组件命名

组件始终使用PascalCase,实例使用camelCase。

bad

1
2
3
import reservationCard from './ReservationCard';

const ReservationItem = <ReservationCard />;

good

1
2
3
import ReservationCard from './ReservationCard';

const reservationItem = <ReservationCard />;

14. 保留的prop命名

不要在组件之间传递props时使用DOM组件的prop名称,因为其他人可能不期望这些名称。

bad

1
2
3
<MyComponent style="dark" />

<MyComponent className="dark" />

good

1
<MyComponent variant="fancy" />

15. 引号

对 JSX 属性使用双引号,对所有其他 JS 使用单引号。

bad

1
2
3
<Foo bar='bar' />

<Foo style={{ left: "20px" }} />

good

1
2
3
<Foo bar="bar" />

<Foo style={{ left: '20px' }} />

16. prop命名

始终使用camelCase作为prop名称,如果prop值为React组件,则使用PascalCase。

bad

1
2
3
4
<Component
UserName="hello"
phone_number={12345678}
/>

good

1
2
3
4
5
<MyComponent
userName="hello"
phoneNumber={12345678}
Component={SomeComponent}
/>

17. 把多行的JSX用括号包裹

如果组件跨多行,请始终将其包装在括号中。

bad

1
2
3
return <MyComponent variant="long">
<MyChild />
</MyComponent>;

good

1
2
3
4
5
return (
<MyComponent variant="long">
<MyChild />
</MyComponent>
);

18. 使用自闭合标签

如果您的组件没有任何子组件,请使用自闭合标签。它提高了可读性。

bad

1
<SomeComponent variant="stuff"></SomeComponent>

good

1
<SomeComponent variant="stuff" />

19. 方法名中不要使用下划线

不要在任何内部React方法中使用下划线。

bad

1
2
3
const _onClickHandler = () => {
// do stuff
}

good

1
2
3
const onClickHandler = () => {
// do stuff
};

20. alt属性

<img>标签中始终包含alt属性。并且不要在alt属性中使用pictureimage,因为屏幕阅读器已经将img元素宣布为图像。不需要包含它们。

bad

1
2
3
<img src="hello.jpg" />

<img src="hello.jpg" alt="Picture of me waving hello" />

good

1
<img src="hello.jpg" alt="Me waving hello" />

21. 优雅地使用CSS

写行内样式太麻烦了,且不易维护。由于在 ReactCSS 没有像 Vue 中的作用域 (scoped) 概念, 如果使用直接引入的方式那么所有的 CSS 样式都是作用域全局的,这样就使 CSS 异常的混乱,有可能导致页面样式相互影响。

bad

1
2
3
4
5
const bodyStyle = {
height: "10px"
};

return <section style={bodyStyle} />;

good

react-scripts@2.0.0 或者更高的版本中已经支持 CSS 的模块化了 (也就不需要手动去修改 webpack.config.js 中的配置了),你只需要以 [name].module.css 方式命名就可以了。

1
2
3
4
/* index.module.css */
.body {
height: 10px;
}

组件里面使用:

1
2
3
import styles from './index.module.css'

return <section className={styles.body} />;

就是这样啦。如果您已经做到了这一步,那么恭喜您!我希望您从本文中学到一两件事。

我希望您有一个美好的一天!:D

相关链接

[1] 21 Best Practices for a Clean React Project