本文将从 render 函数的角度总结 React App 的优化技巧。需要提醒的是,文中将涉及 React 16.8.2 版本的内容(也即 Hooks),因此请至少了解 useState 以保证食用效果。
正文开始。
当我们讨论 React App 的性能问题时,组件的 渲染 速度是一个重要问题。在进入到具体优化建议之前,我们先要理解以下 3 点:
- 当我们在说「render」时,我们在说什么?
- 什么时候会执行「render」?
- 在「render」过程中会发生什么?
解读 render 函数
这部分涉及 reconciliation 和 diffing 的概念,当然官方文档在 这里 。
当我们在说「render」时,我们在说什么?
这个问题其实写过 React 的人都会知道,这里再简单说下:
在 class 组件中,我们指的是 render 方法:
- class Foo extends React.Component {
- render() {
- return <h1> Foo </h1>;
- }
- }
在函数式组件中,我们指的是函数组件本身:
- function Foo() {
- return <h1> Foo </h1>;
- }
什么时候会执行「render」?
render 函数会在两种场景下被调用:
1. 状态更新时
a. 继承自 React.Component 的 class 组件更新状态时
- import React from "react";
- import ReactDOM from "react-dom";
-
- class App extends React.Component {
- render() {
- return <Foo />;
- }
- }
-
- class Foo extends React.Component {
- state = { count: 0 };
-
- increment = () => {
- const { count } = this.state;
-
- const newCount = count < 10 ? count + 1 : count;
-
- this.setState({ count: newCount });
- };
-
- render() {
- const { count } = this.state;
- console.log("Foo render");
-
- return (
- <div>
- <h1> {count} </h1>
- <button onClick={this.increment}>Increment</button>
- </div>
- );
- }
- }
-
- const rootElement = document.getElementById("root");
- ReactDOM.render(<App />, rootElement);
可以看到,代码中的逻辑是我们点击就会更新 count,到 10 以后,就会维持在 10。增加一个 console.log,这样我们就可以知道 render 是否被调用了。从执行结果可以知道,即使 count 到了 10 以上,render 仍然会被调用。
总结:继承了 React.Component 的 class 组件,即使状态没变化,只要调用了setState 就会触发 render。
b. 函数式组件更新状态时
我们用函数实现相同的组件,当然因为要有状态,我们用上了 useState hook:
- import React, { useState } from "react";
- import ReactDOM from "react-dom";
-
- class App extends React.Component {
- render() {
- return <Foo />;
- }
- }
-
- function Foo() {
- const [count, setCount] = useState(0);
-
- function increment() {
- const newCount = count < 10 ? count + 1 : count;
- setCount(newCount);
- }
-
- console.log("Foo render");
-
- return (
- <div>
- <h1> {count} </h1>
- <button onClick={increment}>Increment</button>
- </div>
- );
- }
-
- const rootElement = document.getElementById("root");
- ReactDOM.render(<App />, rootElement);
(编辑:ASP站长网)
|