Skip to main content

React 知识清单

一、基础概念

  • JSX (JavaScript XML): JavaScript 的语法扩展,允许在 JavaScript 代码中写 HTML。
  • 元素 (Elements): React 应用的最小单位,用于描述在屏幕上看到的内容。
  • 组件 (Components): 构建 React 应用的基础块,可复用且独立。

二、组件

  • 函数组件: 使用 JavaScript 函数创建的组件,可以接受 props。
  • 类组件: 使用 ES6 类创建的组件,拥有更多特性,可以有状态 (state) 和生命周期方法。
  • 组件的 Props: 组件的输入,用于父子组件之间传递数据。
  • 组件的 State: 组件的内部状态,可变。

三、生命周期

diagram link

  • 挂载(Mounting):组件被创建并插入 DOM 中的过程。
  • 更新(Updating):组件的 props 或 state 发生变化时的更新过程。
  • 卸载(Unmounting):组件从 DOM 中移除的过程。
  • 错误处理 (Error Handling): 捕获子组件的错误。

四、Hooks

React 16.8 引入的新特性,用于在函数组件中使用 state 和生命周期等特性。

  • useState: 在函数组件中添加状态。
  • useEffect:在函数组件中处理副作用(如数据获取、订阅等)。
  • useContext: 共享状态的更简单方式。
  • useReducer: 用于复杂状态逻辑的 Hook,类似于 Redux。更复杂或大型状态的管理,接受两个参数,第一个参数是一个 reducer,第二个参数是 state 的初始状态。
  • useCallback: 缓存回调函数。
  • useMemo: 缓存计算结果。
  • useRef: 引用 DOM 元素。
  • 自定义 Hooks: 封装和共享逻辑。

五、高级指南

  • Context: 在整个组件树中共享数据,提供一种在组件树中传递数据的方法,无需显式传递 props。
  • 错误边界 (Error Boundaries): 捕获子组件树的 JavaScript 错误。
  • Refs: 访问 DOM 节点。
  • Fragments: 组合多个元素。
  • 高阶组件 (HOCs): 用于组件逻辑复用的高级技术,一种利用函数从组件生成新组件的技术。
  • Render Props: 使用函数类型的 Props 共享代码。

六、性能优化

  • React.memo: 防止不必要的渲染。
  • useMemo 和 useCallback:优化性能,减少不必要的计算和渲染。
  • PureComponent: 仅在 Props 或 State 更改时渲染。
  • 懒加载: 使用 React.lazySuspense

七、路由

  • React Router: 用于构建单页面应用(SPA)的路由管理库。

八、状态管理

  • Redux:用于全局状态管理的库,常用于大型应用。

  • MobX:另一种流行的状态管理库,基于可观察对象。

九、类型检查

  • PropTypes:类型检查工具,用于验证组件的 props。
  • TypeScript:JavaScript 的超集,提供强类型和编译时类型检查。

十、测试

  • Jest:JavaScript 的测试框架,常用于 React 应用。
  • React Testing Library:用于测试 React 组件的库,简化的组件测试。

测试类型

  • 单元测试 Unit Testing: 测试应用程序中最小的部分(通常是单个函数或组件)。
  • 集成测试 Integration Testing: 测试应用程序中多个单元(函数、组件或模块)之间的交互。
  • 端到端测试 End-to-End Testing, E2E Testing: 测试整个应用程序的流程,从开始到结束,就像真实用户操作一样。

单元测试 Unit Testing

add.js
function add(a, b) {
return a + b;
}

module.exports = add;
add.test.js
const add = require("./add");

test("adds 1 + 2 to equal 3", () => {
expect(add(1, 2)).toBe(3);
});

集成测试 Integration Testing

考虑一个用户登陆的场景,其中涉及用户输入处理和认证服务:

login.js
function loginUser(username, password, authService) {
if (!username || !password) {
throw new Error("Username and password are required");
}
return authService.authenticate(username, password);
}

module.exports = loginUser;

对于集成测试,你可以模拟 authService:

login.test.js
const loginUser = require("./login");

const mockAuthService = {
authenticate: jest.fn(),
};

test("calls authenticate with correct credentials", () => {
loginUser("user", "pass", mockAuthService);
expect(mockAuthService.authenticate).toHaveBeenCalledWith("user", "pass");
});

测试本身(在 test 块中)调用了 loginUser 函数,传入一个假设的用户名('user')、密码('pass')以及刚才创建的模拟的认证服务。然后,我们使用 expecttoHaveBeenCalledWith 来检查 mockAuthService.authenticate 是否被正确调用,并且传入了正确的用户名和密码。

端到端测试 End-to-End Testing, E2E Testing

对于 E2E 测试,通常会使用工具如 Cypress 或 Selenium。这里是一个使用 Cypress 对网页进行端到端测试的例子:

首先,确保你有一个网页,例如一个带有登录表单的页面:

index.html
<form id="login-form">
<input type="text" id="username" />
<input type="password" id="password" />
<button type="submit">Login</button>
</form>

然后使用 Cypress 进行 E2E 测试:

e2e.test.js
describe("Login Form", () => {
it("successfully logs in", () => {
cy.visit("http://localhost:3000"); // 修改为你的服务器地址
cy.get("#username").type("user");
cy.get("#password").type("pass");
cy.get("#login-form").submit();
// 这里添加对登录成功的断言
});
});

在这个 E2E 测试示例中,Cypress 会打开浏览器,访问指定的 URL,并模拟用户的输入行为,然后提交表单。

十一、最佳实践

  • 组件拆分:保持组件小而专注。
  • 可维护的代码:遵循清晰的项目结构和编码规范。
  • 性能考虑:合理使用状态和 props,避免不必要的渲染。

十二、其他

  • Portals: 在父组件的 DOM 层次之外渲染子组件。
  • Suspense for Data Fetching: 数据获取的新模式。
  • Concurrent Mode: 实验性功能,提高应用响应性。