本篇文章目的:不使用任何React性能优化API实现性能优化。
请看如下例子,每次点击按钮,父组件(App)状态更新都会引起子组件(Child)的重新渲染,造成了不必要的性能开销。
import React, { useState } from "react";
export default function App() {
const [num, setNum] = useState(0);
return (
<>
<h1>num is {num}</h1>
<button
onClick={(e) => {
setNum(() => num + 1);
}}
> + </button>
<Child />
</>
);
}
function Child() {
console.log("Child render");
return <h2>Child</h2>;
}
接下来,我们遵循将变的部分(props,state,context)与不变部分分离的原则稍微把代码改造下再看看效果...
第一种写法如下:
import React, { useState } from "react";
export default function App() {
return (
<>
<Button />
<Child />
</>
);
}
function Button() {
const [num, setNum] = useState(0);
return (
<>
<h1>num is {num}</h1>
<button
onClick={(e) => {
setNum(() => num + 1);
}}
>
+
</button>
</>
);
}
function Child() {
console.log("Child render");
return <h2>Child</h2>;
}
从上面代码可以看到,我们写了一个Button组件,把App组件里面可变的状态useState提取到了Button组件。现在点击按钮更新状态不再会引起Child组件的重新渲染,这样是不是就达到了我们想要的效果。
第二种写法:
import React, { useState } from "react";
export default function App() {
return (
<>
<Button>
<Child />
</Button>
</>
);
}
function Button({ children }) {
const [num, setNum] = useState(0);
return (
<>
<h1>num is {num}</h1>
<button
onClick={(e) => {
setNum(() => num + 1);
}}
>
+
</button>
{children}
</>
);
}
function Child() {
console.log("Child render");
return <h2>Child</h2>;
}
从上面代码可以看到,我们也是把App组件里面可变的状态useState提取到了Button组件。现在点击按钮更新状态也不再会引起Child组件的重新渲染,这样也达到了我们想要的效果。
这是为什么呢?
上面说了这个概念将变的部分(props,state,context)与不变部分分离,上面两种写法都是对父组件(App)操作的,将App组件变化的部分抽离到单独的组件,实际上达到优化效果的是Child组件。从而我们发现一个规律,当父组件满足性能优化条件时,子孙组件可能命中性能优化。从而实现不使用React任何性能优化Api也达到性能优化。