[英]When does React.memo() compare component props?
據我所知,React.memo() 會比較 props 以查看組件是否應該重新渲染。 但是如果之前的 props 和當前的 props 相同,即使組件沒有被 React.memo() 包裹,React 也不會重新渲染組件。 那么,react.memo() 在組件重新評估之前比較道具,而不是在重新渲染之前?
它在渲染之前比較它們,與沒有React.memo()
相同。
但是如果你的 props 沒有改變,你認為 React 不會重新渲染你的組件是不正確的。 如果您的父組件之一的道具/狀態已更改,它將重新渲染該組件的所有子(和孫子),即使它們的道具沒有更改。
因此,在其中一個孩子上使用React.memo()
可以防止重新渲染樹的那個分支,如果它的道具實際上沒有改變的話。
但是如果之前的 props 和當前的 props 相同,即使組件沒有被 React.memo() 包裹,React 也不會重新渲染組件。
確實如此,無論是在功能組件中:
const Child = () => { console.log('child rendering'); return 'foo'; }; const App = () => { const [parentState, setParentState] = React.useState(0); React.useEffect(() => { setParentState(1); }, []); return ( <div> <div>{parentState}</div> <Child /> </div> ); }; ReactDOM.createRoot(document.querySelector('.react')).render(<App />);
<script crossorigin src="https://unpkg.com/react@18/umd/react.development.js"></script> <script crossorigin src="https://unpkg.com/react-dom@18/umd/react-dom.development.js"></script> <div class='react'></div>
在 class 組件中:
class Child extends React.Component { render() { console.log('child rendering'); return 'foo'; } } class App extends React.Component { parentState = 0; componentDidMount() { this.setState({ parentState: 1 }); } render() { return ( <div> <div>{this.parentState}</div> <Child /> </div> ); } }; ReactDOM.createRoot(document.querySelector('.react')).render(<App />);
<script crossorigin src="https://unpkg.com/react@18/umd/react.development.js"></script> <script crossorigin src="https://unpkg.com/react-dom@18/umd/react-dom.development.js"></script> <div class='react'></div>
除非您已設置以某種方式記憶組件,否則即使 props 和 state 都沒有更改,組件也會重新渲染。
React.memo
進行比較以確定組件是否應該在組件被調用時重新渲染。 也就是說,如果你有
const SomeComponent = React.memo(function MyComponent(props) {
// ...
然后React.memo
將在引擎在渲染時遇到對SomeComponent
的調用時執行比較,例如:
const App = () => {
return (
<div>
<SomeComponent />
</div>
);
};
上面,每當 App 重新渲染時, SomeComponent 都會再次被調用。 React.memo
然后決定是否需要重新運行底層組件,或者是否可以重用之前渲染返回的值。 如果確實需要重新運行,那么它將運行原始的MyComponent
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.