【问题标题】:Rendering only one child component after state change状态改变后只渲染一个子组件
【发布时间】:2021-10-18 12:49:30
【问题描述】:

我已经构建了一个 React 组件,它有两个子组件:一个显示图表 (vis.js),当用户将鼠标悬停在图表中的某个节点上时,主组件会通过状态更改来了解这一点。唯一使用此状态的子元素是 div(图表的兄弟)。

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

这是我的代码:

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() 不以任何方式依赖于状态。

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

【问题讨论】:

  • 你试过 useMemo() 吗?
  • 你可以memoVis组件。

标签: javascript reactjs use-state vis.js


【解决方案1】:

您可以使用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>
    </>
  );
};

【讨论】:

    【解决方案2】:

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

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

    【讨论】:

    • 使用备忘录对我不起作用。
    猜你喜欢
    • 2019-09-21
    • 2020-06-26
    • 2020-12-30
    • 2018-12-31
    • 2020-04-07
    • 1970-01-01
    • 1970-01-01
    • 2018-04-20
    • 2020-10-07
    相关资源
    最近更新 更多