1

我有以下代码(codesandbox 并粘贴在此处),它需要组件上的 React.memo Speaker。我不明白为什么有必要,因为我认为memo所做的只是检查道具是否发生了变化。对于 clickCount 不变的发言者,我不明白为什么需要备忘录。

https://codesandbox.io/s/festive-herschel-ptzln?file=/pages/index.js:0-1613

import React, { useState, memo, useCallback } from 'react';

const Speaker = memo(({ speaker, speakerClick }) => {
  console.log(speaker.id);
  return (
    <div className="speaker-col">
      <span
        onClick={() => {
          speakerClick(speaker.id);
        }}
      >
        {speaker.id} {speaker.name}
      </span>
      &nbsp;&nbsp;
      <span className="fa fa-star ">&nbsp;&nbsp;{speaker.clickCount}</span>
      &nbsp;
    </div>
  );
});

function SpeakerList({ speakers, setSpeakers }) {

  const speakerClick = useCallback(
    (id) => {
      // passing a callback avoid using a stale object reference
      setSpeakers((speakers) => {
        return speakers.map((speaker) => {
          return speaker.id === id
            ? { ...speaker, clickCount: speaker.clickCount + 1 }
            : speaker;
        });
      });
    },
    [setSpeakers], // you can add setSpeakers as dependency since no change
  );

  return (
    <div>
      {speakers.map((speaker) => {
        return (
          <Speaker
            speaker={speaker}
            speakerClick={speakerClick}
            key={speaker.id}
          />
        );
      })}
    </div>
  );
}

//
const App = () => {
  const speakersArray = [
    { id: 1124, name: 'aaa', clickCount: 0 },
    { id: 1530, name: 'bbb', clickCount: 0 },
    { id: 10803, name: 'ccc', clickCount: 0 },
  ];

  const [speakers, setSpeakers] = useState(speakersArray);

  return (
    <div className="speakers-list">
      <h1>Speaker List</h1>
      <SpeakerList
        speakers={speakers}
        setSpeakers={setSpeakers}
      />
    </div>
  );
};

export default App;
4

2 回答 2

2

memo是更高阶component。如果component renders给定相同的结果相同,则可以在某些情况下通过结果将其包装在对aprops的调用中。这意味着将跳过渲染组件,并重用上次渲染的结果。您的组件将被渲染一次,并且在需要的地方将重用它,这将提高它的性能。React. memoperformance boostmemoizingReactReactprevious render

在您的情况下,您似乎没有改变,所以这里的speakers目的是避免每次需要组件时都使用它,而是只会在一个地方渲染一次并缓存它,然后在另一个地方需要它时缓存它它不会使用.renderingSpeakerre-renderReactcached result

于 2021-02-06T20:29:19.050 回答
1

React.memo是性能优化。正如您所说,如果正在请求具有相同道具的渲染,它会返回一个记忆化的渲染结果。

这意味着它仅与经常使用相同道具渲染的组件相关,或者渲染成本高(因为许多或大型子组件)。

在这种特殊情况下,如果扬声器不同,则好处可能很小,除非经常渲染封闭组件。

于 2021-02-06T20:20:31.717 回答