前言

在之前的文章中,我列举了一些 React 常用的 Hooks。其中一些 Hooks 如 React.memo,useMemo 等 hooks 可以缓存结果,但是这不代表我们可以无脑的缓存,因为内存的开销也是很昂贵的。

组件化

import React from "react";

const Expensive = () => {
  console.log("expensive compenent rendered!");

  let total = 0;
  for (let i = 0; i < 1000000000; i++) {
    total += i;
  }

  return <div>Expensive</div>;
};

export default Expensive;

// const Expensive = React.memo(() => {
//   console.log("expensive compenent rendered!");

//   let total = 0;
//   for (let i = 0; i < 1000000000; i++) {
//     total += i;
//   }

//   return <div>Expensive</div>;
// });

// export default Expensive;

组件之间分开,规避状态改变重新渲染组件

import { useEffect, useMemo, useState } from "react";
import Expensive from "./Expensive";

function App4() {
  //   const [name, setName] = useState("");

  //   return (
  //     <div>
  //       <input onChange={(e) => setName(e.target.value)} placeholder="name" />
  //       <Expensive />
  //     </div>
  //   );
  // }

  return (
    <div>
      <Form />
      <Expensive />
    </div>
  );
}

const Form = () => {
  const [name, setName] = useState("");
  return <input onChange={(e) => setName(e.target.value)} placeholder="name" />;
};

export default App4;

这样的话,form 表单改变也不会说重新导致 Expensive 组件的渲染

父子组件交换数据

那么如果父组件又需要子组件的值呢,子组件改变值,也会导致其他子组件改变。

import { useEffect, useMemo, useState } from "react";
import Expensive from "./Expensive";

function App5() {
  // const [backgroundColor, setBackgroundColor] = useState("white");

  // return (
  //   <div style={{ backgroundColor }}>
  //     <input onChange={(e) => setBackgroundColor(e.target.value)} />
  //     <Expensive />
  //   </div>
  // );

  return (
    <BgProvider>
      <Expensive />
    </BgProvider>
  );
}

const BgProvider = ({ children }) => {
  let [backgroundColor, setBackgroundColor] = useState("white");
  return (
    <div style={{ backgroundColor }}>
      <input onChange={(e) => setBackgroundColor(e.target.value)} />
      {children}
    </div>
  );
};

export default App5;

我们可以通过组件之间的包裹,来完成。这样的话 children 由于没有改变所以不大会导致重新渲染