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示例!
答案 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在每个状态变化时都会重新渲染,因此您会看到结果。