状态更改后仅渲染一个 child 组件

Rendering only one child component after state change

我构建了一个包含两个 children 的 React 组件:一个显示图形 (vis.js),当用户将鼠标悬停在图形中的一个节点上时,主要组件会被感知这是由状态变化引起的。唯一使用此状态的 child 是 div(该图的同级)。

但是,当状态发生变化时,所有children(包括图形)都是re-rendered。我不想每次将鼠标悬停在节点上时都渲染图形,只是它的兄弟节点。

这是我的代码:

import React, { useState } from "react";
...

const Graph = (props) => {

  ...

  const [nodeName, setNodeName] = useState("");

  function handleHoverEvent(node) {
    if (nodeName !== node) {
      setNodeName(node);
    }
  }

  function makeNodes() {
    ...
  }

  function makeEdges() {
    ...
  }

  return (
    <div>
      <Vis
        nodes={makeNodes()}
        edges={makeEdges()}
        OnHover={handleHoverEvent}
      />
      <NameDisplay name={nodeName} />
    </div>
  );
}

...



export default Graph;

makeNodes()makeEdges() 不以任何方式依赖于状态。

如何防止图表每次都是 re-rendered?我需要做的就是将数据从一个 child“铲”到另一个 child,同时只更新其中一个。

您可以使用 React.memo()React.useCallback 来避免在 React 组件中重新渲染内容。 Avoiding React component re-renders with React.memo

示例:

按钮

import React from "react";

interface IProps {
  handleClick: () => void;
  children: any;
}

function Button({ handleClick, children }: IProps) {
  console.log("Rendering button - ", children);
  return <button onClick={handleClick}>{children}</button>;
}

export default React.memo(Button);

计数

    import React from "react";
    import Button from './Button'
    
    interface IProps {
      text: any;
      count: any;
      handleClick: () => void;
      children: any;
    }
    
    function Count({ text, count, handleClick, children }: IProps) {
      console.log(`Rendering ${text}`);
      return (
        <div>
        <div>
          {text} - {count}
        </div>
        <Button handleClick={handleClick}>{children}</Button>
        </div>
      );
    }

export default React.memo(Count);

父组件

import React, { useState, useCallback } from "react";
import Count from "./Count";

export const ParentComponent = () => {
  const [age, setAge] = useState(25);
  const [salary, setSalary] = useState(50000);

//   const incrementAge = () => {
//      setAge(age + 1)
//   }

//   const incrementSalary = () => {
//      setSalary(salary + 1000)
//   }

  const incrementAge = useCallback(() => {
    setAge(age + 1);
  }, [age]);

  const incrementSalary = useCallback(() => {
    setSalary(salary + 1000);
  }, [salary]);

  return (
    <>
      <Count text="Age" count={age} handleClick={incrementAge}>
        Increment Age
      </Count>
      <Count text="Salary" count={salary} handleClick={incrementSalary}>
        Increment Salary
      </Count>
    </>
  );
};

只需将所有组件转换为 ES6 类。此处对此进行了描述:https://reactjs.org/docs/state-and-lifecycle.html#converting-a-function-to-a-class

我什至不必指定 shouldComponentUpdate() 方法。