如果在另一个功能组件中定义,React功能组件会重新渲染整个组件

时间:2020-03-30 08:33:50

标签: reactjs react-dom react-functional-component


const List = props => {
  const SubList = (number, key) => <p key={number}>{number}</p>;

  const WholeList = () => props.numbers.map(SubList);

  // method 1 return (<WholeList/>)
  // method 2 return props.numbers.map(SubList);
};

function App() {
  const [numbers, setNumbers] = useState([1, 2, 3, 4, 5]);

  return (
    <>
      <button onClick={() => setNumbers([...numbers, numbers.length + 1])}>
        Plus one
      </button>
      <List numbers={numbers} />
    </>
  );
}

方法1和2呈现完全相同的东西,除了它们的重新呈现行为不同。

在方法1中,当我单击Plus One并检查DOM时,我发现整个列表都已重新呈现。如果改为使用方法2,则仅将新添加的数字插入DOM。我发现它们都有用例,但是我不确定其行为。任何人都可以阐明这种行为吗?我以前从未在React中使用过class-component的事实会引起困惑吗?

我在这里有一个codesandbox示例!

2 个答案:

答案 0 :(得分:0)

我发现我的问题是Why does React discard the entire DOM subtree and recreate it from scratch?的重复

简而言之,渲染组件中定义的功能组件将每次重新创建。尽管React无法渲染新功能,但React无法区分渲染结果。

React可以查看道具更改并决定是否应重新渲染功能组件。

在我最初的问题中,const WholeList = () => props.numbers.map(SubList);是在List中定义的,因此每次List重新发布时都会重新创建。 React无法可靠地判断WholeList是否已更改,因此无法重新提交它。

在情况2中,呈现结果是确定性的,它是<p>的列表。 React可以比较之前的结果和新的结果。请参阅反应Reconciliation

答案 1 :(得分:0)

因为这样做是因为“方法1 return()”,所以您将WholeList视为功能组件,因为FC在每个状态变化时都会重新渲染,因此您会看到结果。