React 由于太过灵活,10 个人写能写出 10 种甚至 9 种写法(绝望)。俗话说乱写一时爽,维护火葬场(自己说的),因此这篇文章总结了我日常开发见到的各种不合理写法,和自己写出整洁代码的一些经验。
组件结构
组件结构建议分为四大块(有顺序):状态 Hook 调用(useState)、副作用 Hook 调用(useEffect)、方法定义、渲染逻辑。
示例:
function Component({ children }) {
// 状态 Hook 调用
const [state, setState] = useState(false);
// 也可以在这里定义 Effect 要用到的纯函数,记住不能使用任何函数外的变量
// 纯函数也可以考虑单独拆出来,可能将来在别的组件也会用到
// 副作用 Hook 调用
useEffect(() => {}, []);
// 方法定义,尽量使用箭头函数
const fn = () => {};
// 渲染逻辑
// 如果后面渲染表达式过于复杂,可以单独抽出来放着,命名为 renderXXX
// 更好的做法还是单独抽出一个组件
const renderXXX = () => <p></p>;
return <p>{children}</p>;
}
这是个人习惯的做法。好处就是可以很清晰分清楚不同逻辑块。
常用 Hook 逻辑抽离
就是把常用到的 Hook 逻辑单独抽离出来,方便维护。
如果不知道该怎么拆,可以记住一个方法:如果实现一个逻辑需要用到多个 Hook、多个变量,而且这个逻辑还可能在别的组件中使用,拆它就完事了。
示例:
function Component() {
// 错误,维护起来非常不方便
const [info, setInfo] = useState(null);
useEffect(() => {
fetchInfo()
.then((resp) => setInfo(resp));
}, []);
// 正确,可能这个 info 还会在其他组件用到,这样可以复用代码也方便维护
const info = useInfo();
}
推荐使用 ahooks - React Hooks Library - ahooks 3.0,里面封装了很多非常常用的逻辑,很方便使用。
组件能拆尽拆
组件高度拆分能极大提升代码可维护性。特别是如果你用了 CSS-in-JS,如果不拆的话代码会非常多的。
当然,也没必要搞极端把组件拆的太多,这样反而还会增加工作量。
示例:
// 错误
function App() {
const list = [1, 2, 3, 4];
return (
<div>
<h1>标题</h1>
<ul>
{list.map(item => <li key={item}>{item}</li>)}
</ul>
<p>还有其他一堆东西</p>
</div>
);
}
// 正确
function ListItem({ children }) {
return (
<li>{children}</li>
);
}
function List({ list }) {
return (
<ul>{list.map(item => <ListItem key={item}>{item}</ListItem>)}</ul>
);
}
function App() {
const list = [1, 2, 3, 4];
return (
<div>
<h1>标题</h1>
<List list={list} />
<p>还有其他一堆东西</p>
</div>
);
}
一个文件应当只有一个组件,上面只是为了方便演示就都放一个文件里面了,目录结构可以阅读我之前写的一篇文章:
避免使用无意义 useCallback
和他人合作开发时经常见到乱用 useCallback,估计是没理解 useCallback 的正确用法,可以看我往期的文章:
React useCallback & useMemo 实用技巧(性能优化)
函数式编程
函数式编程能使代码更容易理解和维护,善用 lodash。复杂逻辑善用 lodash.chain。
示例:
const list = [1, 2, 3, 4];
// 错误
const children = [];
for (const item of list) {
children.push(<p key={item}>{item}</p>);
}
// 正确
const children = list.map(item => <p key={item}>{item}</p>);
尝试使用 CSS Utility Library
现有的不论是 CSS-in-JS,还是 CSS Modules,写起来都还是感觉比较繁琐。
CSS-in-JS 很容易把代码写的太长,而且现阶段也很难支持媒体查询和伪元素 & 伪类。
CSS Modules 还要想怎么去命名,使用 CSS 预处理器的话嵌套也会很容易乱。
所以可以尝试试试 CSS Utility Library,比如 Tailwind CSS。我已经在项目中使用了,真的是用了后就再也回不去了。