【问题标题】:How to render only subchild without rendering all high level component如何仅渲染子子项而不渲染所有高级组件
【发布时间】:2021-05-08 19:08:40
【问题描述】:

我有一个子子组件,它位于父组件的循环中。当子子组件之一正在更新父组件的状态时,它会重新渲染所有子组件,因为它是循环的。我怎样才能避免每次迭代的重新渲染。它应该更新那个特定的子孩子。

import React, { useState } from "react";

function Parent() {
  const [selectedChild, setSelectedChild] = useState([]);

  const onChangeHandle = (event, id) => {
    const checked = event.target.checked;
    let updatedArray = [...selectedChild];
    if (checked) {
      if (!selectedChild.includes(id)) {
        updatedArray.push(id);
      }
    } else {
      var index = updatedArray.indexOf(id);
      if (index !== -1) {
        updatedArray.splice(index, 1);
      }
    }
    setSelectedChild(updatedArray);
  };

  return (
    <div>
      <table>
        <tbody>
          {[1, 2, 3].map((value, index) => {
            return (
              <Child
                key={index}
                index={index}
                value={value}
                handle={onChangeHandle}
                isSelected={selectedChild.includes(index)}
              />
            );
          })}
        </tbody>
      </table>
      <div>{selectedChild}</div>
    </div>
  );
}

function Child({ index, value, handle, isSelected }) {
  console.log("rendering child");

  return (
    <tr>
      <td>
        <SubChild
          isChecked={isSelected}
          onChangeHandle={handle}
          index={index}
        />
      </td>
      <td>
        hello {index} {value}
      </td>
    </tr>
  );
}

function SubChild({ isChecked, onChangeHandle, index }) {
  console.log("rendering subchild");

  return (
    <input
      type="checkbox"
      checked={isChecked}
      onChange={(event) => onChangeHandle(event, index)}
    />
  );
}

export default function App() {
  return (
    <div className="App">
      <Parent />
    </div>
  );
}

当前行为:在上面的代码中,当我单击其中一个子组件中的复选框(子子组件)时,它正在更新父组件状态(selectedChild)。所以循环正在执行,所有子项(所有表行)都在重新渲染。

预期行为:只有那个特定的子孩子必须重新渲染(即使它不应该重新渲染孩子)

演示https://codesandbox.io/s/reactqa2-0c0md?file=/src/App.js

小相关问题How to avoid rerender all child components which in loop when parent component state update

【问题讨论】:

    标签: javascript reactjs performance react-hooks react-memo


    【解决方案1】:

    您应该使用 memoization (useCallback/React.memo) 并使用功能更新重写句柄逻辑。

    此外,您避免 Child 进行渲染,因为您在渲染后有一个新的 value

    // Make a stable callback
    const onChangeHandle = useCallback((event, id) => {
      setSelectedChild((updatedArray) => {
        if (event.target.checked) {
          if (!updatedArray.includes(id)) {
            return [...updatedArray, id];
          }
        } else {
          return updatedArray.filter((currId) => currId !== id);
        }
        return updatedArray;
      });
    }, []);
    
    // Memoize the component
    const MemoChild = React.memo(Child);
    const MemoSubChild = React.memo(SubChild);
    

    【讨论】:

      猜你喜欢
      • 2019-06-20
      • 2017-03-16
      • 1970-01-01
      • 2020-02-13
      • 2021-03-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-07-20
      相关资源
      最近更新 更多