假如这条提议可以让我们停止不须要的从头渲染,那我们为什么不把每个 class 组件酿成 PureComponent、把每个函数式组件用 React.memo 包起来?为什么有了更好的要领还要保存 React.Component 呢?为什么函数式组件不默认影象化呢?
毫无疑问,这些要领并不老是万仙丹。
嵌套工具的题目
我们先来思量下 PureComponent 和 React.memo 的组件到底做了什么?
每次更新的时辰(包罗状态更新或上层组件从头渲染),它们就会在新 props、state 和旧 props、state 之间对 key 和 value 举办浅较量。浅较量是个严酷相称的搜查,假如检测到差别,render 就会执行:
- // 根基范例的较量
- shallowCompare({ name: 'bar'}, { name: 'bar'}); // output: true
- shallowCompare({ name: 'bar'}, { name: 'bar1'}); // output: false
尽量根基范例(如字符串、数字、布尔)的较量可以事变的很好,但工具这类伟大的环境也许就会带来意想不到的举动:
- shallowCompare({ name: {first: 'John', last: 'Schilling'}},
- { name: {first: 'John', last: 'Schilling'}}); // output: false
上述两个 name 对应的工具的引用是差异的。
我们从头看下之前的例子,然后修改我们传入 Bar 的 props:
- import React, { useState } from "react";
- import ReactDOM from "react-dom";
-
- const Bar = React.memo(function Bar({ name: { first, last } }) {
- console.log("Bar render");
-
- return (
- <h1>
- {first} {last}
- </h1>
- );
- });
-
- function Foo({ hideFoo }) {
- return (
- <>
- <h1>Foo</h1>
- <button onClick={hideFoo}>Hide Foo</button>
- </>
- );
- }
-
- function App() {
- const [isFooVisible, setFooVisibility] = useState(false);
-
- return (
- <div className="App">
- {isFooVisible ? (
- <Foo hideFoo={() => setFooVisibility(false)} />
- ) : (
- <button onClick={() => setFooVisibility(true)}>Show Foo</button>
- )}
- <Bar name={{ first: "John", last: "Schilling" }} />
- </div>
- );
- }
-
- const rootElement = document.getElementById("root");
- ReactDOM.render(<App />, rootElement);
尽量 Bar 做了影象化且 props 值并没有产生变换,每次父组件从头渲染时它如故会从头渲染。这是由于尽量每次较量的两个工具拥有沟通的值,引用并差异。
函数 props 的题目
我们也可以把函数作为 props 向组件转达,虽然,在 JavaScript 中函数也会转达引用,因此浅较量也是基于其转达的引用。
因此,假如我们转达的是箭头函数(匿名函数),组件如故会在父组件从头渲染时从头渲染。
Tip #4:更好的 props 写法
前面的题目的一种办理要领是改写我们的 props。
(编辑:湖南网)
【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!
|