React 最佳实践

React 是一个声明式、高效且灵活的 JavaScript 库

一、特性

  • 虚拟 DOM:保存在内存中并通过 ReactDOM 等库与“真实”DOM 同步的 UI 表示。使用这种方法,只有实际更改的组件才会更新到 DOM,而不是所有组件。

  • 声明式:声明式视图使代码更可预测和易于调试。

  • 基于 CDD 开发模式

  • 跨平台 React-Native

区别于命令式,这里拿 for 举例

 1
 2
 3
 4
 5
 6
 7
 8
 9
10

//命令式,我称之为松散式
let n = [-9, 87, 72, 452, 32, -9];
for (let i = 0; i < n.length; i++) {
  console.log(n[i]);
}

//声明式(函数式,封装性更好)
let n = [-9, 87, 72, 452, 32, -9];
n.forEach((v) => console.log(v));

二、目录结构

拿 nextjs 举例

  • pages
    • index.tsx
  • components
    • button.component.tsx
  • public
    • favicon.ico
  • styles
    • global.module.css

三、Hooks

  • Hooks 让你无需编写类即可使用状态和其他 React 功能。
  • 不适用于基于类的组件。

#. 调用 Hooks

  • 不要在循环、条件或嵌套函数中调用 Hook。此外,永远不要从常规 JavaScript 函数调用 Hook。它们应该从 React 功能组件的顶层中调用。

#. 使用 ESLint 插件

可以使用 eslint-plugin-react-hooks 强制从 React 功能组件中和自定义 Hook 中调用 Hook。

1
2

yarn add --dev eslint-plugin-react-hooks
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13

//ESLint 配置
{
  "plugins": [
    // ...
    "react-hooks"
  ],
  "rules": {
    // ...
    "react-hooks/rules-of-hooks": "error", // 检查 Hooks 的规则
    "react-hooks/exhaustive-deps": "warn" // 检查 effect 依赖
  }
}

三、表单验证

  • react-hook-form
  • Formik
  • kendo-react-form

四、JSX 速记

  • 当使用 props 控制组件可见性时
1
2
3
4

showRatings={true}

<Reviews showRatings />

五、类型检查

  • 使用 React.PropTypes
1
2
3
4
5
6
7
8
9

const MyComponent = (props) => {
  const { username } = props;
  return <div>{props.name}</div>;
};

PropTypeMyComponent.PropTypes = {
  name: PropTypes.string.isRequired,
};
  • 使用 TypeScript (首推)
1
2
3
4
5
6
7
8

interface props {
  username?: string;
}

const Mycomponent = ({ username }: props) => {
  return <div>{username}</div>;
};

六、使用 Memo 提升性能

React.Memo 高阶组件环绕组件以记住渲染的输出并跳过不必要的渲染。

1
2
3
4

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

七、使用 Fragments / <></>

React 中的一个常见模式是一个组件返回多个元素。

Fragments 允许你将子列表分组,而无需向 DOM 添加额外节点。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18

return (
   <React.Fragment>
     <ChildA />
     <ChildB />
     <ChildC />
   </React.Fragment>
 );

// or 短语法

return (
   <>
       <ChildA />
       <ChildB />
       <ChildC />
   </>
)