React 相关的工程最佳实践

252 阅读3分钟

原文: 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" />

结尾

试着将它们运用到项目中,让你的代码更易读、更纯粹。