React代码整洁优化实践

整洁的代码不仅仅是正常运行的代码,更是要求易于阅读、简单易懂、组织整齐。
在本文中,我会们将示例几种代码整洁案例。
在阅读这些建议时,要记住这些只是建议! 如果你不同意它们中的任何一个,那也完全没关系。
以下这些实践,个人觉得对我自己编写 React 代码很有帮助。

1. 仅对一个条件进行渲染

如果需要在条件为true时渲染某些内容,而在条件为false时不渲染任何内容,不推荐使用三元表达式,改用与运算符&&,它可以方便地条件渲染一个元素。

优化前:

1
2
3
4
5
6
7
8
9
10
11
import React from "react";

export const TopNav = (props: { showSearch?: boolean }) => {
const { showSearch = false } = props;
return (
<div className="doc-head">
{/* 三元表达式进行条件渲染 */}
{showSearch ? <SearchBox placeholder="输入关键词搜索" onSearch={(keyword) => window.location.assign(`/privatecloud/search?q=${keyword}`)} style={{ marginRight: 100 }} /> : null}
</div>
);
};

优化后:

1
2
3
4
5
6
7
8
9
10
11
import React from "react";

export const TopNav = (props: { showSearch?: boolean }) => {
const { showSearch = false } = props;
return (
<div className="doc-head">
{/* 与运算符&&进行条件渲染 */}
{showSearch && <SearchBox placeholder="输入关键词搜索" onSearch={(keyword) => window.location.assign(`/privatecloud/search?q=${keyword}`)} style={{ marginRight: 100 }} />}
</div>
);
};

2. 每一个条件都可能进行渲染

如果需要在条件为 true 时渲染某些内容,而在条件为 false 时渲染其他内容。推荐使用三元表达式

优化前:

1
2
3
{/* 条件 True 和 False 都要渲染内容 */}
{ good && <p>Good!</p> }
{ !good && <p><b>Not Good!<b></p> }

优化后:

1
2
3
4
5
6
7
8
9
10
11
12
{
/* 三元表达式 */
}
{
good ? (
<p>Good!</p>
) : (
<p>
<b>Not Good!</b>
</p>
);
}

3. 组件 Boolean props 传参

组件接收参数的属性值为布尔类型, 并且传入 true 值时,可以省略填写值,并不会影响组件内取到 true 值

优化前:

1
2
<Hello disabled={true} />
<Hello disabled={false} />

优化后:

1
2
<Hello disabled />
<Hello disabled={false} />

4. 组件 String props 传参

组件 Props 值为 String, 推荐使用双引号包裹,不使用花括号或反引号。

优化前:

1
2
3
<Hello personName={"Jim"} />
<Hello personName={'Tom'} />
<Hello personName={`Ken`} />

优化后:

1
2
3
<Hello personName="Jim" />
<Hello personName="Tom" />
<Hello personName="Ken" />

5. Event handler functions

如果一个事件函数只接受一个参数,不需要传入匿名函数:onChange={ e => handleChange(e) },推荐这种写法(直接等于函数): onChange={ handleChange } 。

优化前:

1
2
3
4
const handleChange = (e) => {
console.info(e.target.value);
};
<input id="name" value={inputValue} onChange={(e) => handleChange(e)} />;

优化后:

1
2
3
4
5
6
7
const handleChange = (e) => {
console.info(e.target.value);
};
{
/* 事件只有一个参数,不需要匿名函数*/
}
<input id="name" value={inputValue} onChange={handleChange} />;

6. components as props

将组件作为参数传递给另一个组件时,如果该组件不接受任何参数,则无需将该传递的组件包装在函数中。

优化前:

1
2
<Hello ClockComponent={() => <Clock timestamp={new Date().getTime()} />} />
<Hello ClockComponent={() => <Clock />} />

优化后:

1
2
<Hello ClockComponent={() => <Clock timestamp={new Date().getTime()} />} />
<Hello ClockComponent={Clock} />

7. 设置 state 依赖先前的 state

如果新 state 依赖于先前 state,则始终将 state 设置为先前 state 的函数。可以批处理 React 状态更新。

优化前:

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

export const Hello = () => {
const [cout, setCount] = useState < number > 0;

// 依赖先前/上一个的state值 (异步调用)
const handleClick = (e) => setCount(cout + 1);

// 期望执行2次 首次执行理应 cout = 2
const handleClickRunDouble = (e) => {
// 执行第二个handleClick执行的时候第一个count设置未完成(异步的),所以还是 count = 0 = 0 + 1 = 1 因此 首次的点击得到的值 = 1 而并非2, 如果需要实现2 那么就得利用setState的批处理方式
handleClick(e);
handleClick(e);
};

return (
<div>
<button onclick={handleClick}>click here</button>
<span>{count}</span>
<button onclick={handleClickRunDouble}>click here & lunch 2 times</button>
</div>
);
};

优化后:

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

export const Hello = () => {
const [cout, setCount] = useState < number > 0;

{
/* 将set调用设置为批处理模式 使用set方法提供的callback内的数值 */
}
const handleClick = (e) => setCount((c) => c + 1);

// 首次调用后会输出最新的值 count = 2;
const handleClickRunDouble = (e) => {
handleClick(e);
handleClick(e);
};

return (
<div>
<button onclick={handleClick}>click here</button>
<span>{count}</span>
<button onclick={handleClickRunDouble}>click here & lunch 2 times</button>
</div>
);
};

以上 7 个就是我推荐和总结的几个React代码整洁优化实践

最后,祝大家开发愉快