简体   繁体   English

React.memo() 什么时候比较组件 props?

[英]When does React.memo() compare component props?

From what I know, React.memo() compares props to see if the component should be re-rendered or not.据我所知,React.memo() 会比较 props 以查看组件是否应该重新渲染。 But React doesn't re-render components if the previous props and current props are the same even when the component is not wrapped by React.memo().但是如果之前的 props 和当前的 props 相同,即使组件没有被 React.memo() 包裹,React 也不会重新渲染组件。 So, react.memo() compares props before component re-evaluation, not before re-render?那么,react.memo() 在组件重新评估之前比较道具,而不是在重新渲染之前?

It compares them just before rendering, same as without React.memo() .它在渲染之前比较它们,与没有React.memo()相同。

But you're not quite right in thinking that React doesn't re-render your component if your props haven't changed.但是如果你的 props 没有改变,你认为 React 不会重新渲染你的组件是不正确的。 If one of your parent components' props/state have changed, it will re-render all of that component's children (and grandchildren), even if their props haven't changed.如果您的父组件之一的道具/状态已更改,它将重新渲染该组件的所有子(和孙子),即使它们的道具没有更改。

So using React.memo() on one of those children prevents the re-rendering of that branch of the tree, if its props haven't actually changed.因此,在其中一个孩子上使用React.memo()可以防止重新渲染树的那个分支,如果它的道具实际上没有改变的话。

But React doesn't re-render components if the previous props and current props are the same even when the component is not wrapped by React.memo().但是如果之前的 props 和当前的 props 相同,即使组件没有被 React.memo() 包裹,React 也不会重新渲染组件。

Sure it does, both in functional components:确实如此,无论是在功能组件中:

 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>

and in class components:在 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>

Unless you've set things up to memoize the component in some way, the component will re-render even if neither props nor state has changed.除非您已设置以某种方式记忆组件,否则即使 props 和 state 都没有更改,组件也会重新渲染。

The comparison that React.memo does to determine whether a component should be re-rendered whenever the component is called . React.memo进行比较以确定组件是否应该在组件被调用时重新渲染。 That is, if you have也就是说,如果你有

const SomeComponent = React.memo(function MyComponent(props) {
  // ...

Then React.memo will perform comparisons whenever the engine, while rendering, comes across a call to SomeComponent , eg:然后React.memo将在引擎在渲染时遇到对SomeComponent的调用时执行比较,例如:

const App = () => {
  return (
    <div>
      <SomeComponent />
    </div>
  );
};

Above, whenever App re-renders, SomeComponent will be called again.上面,每当 App 重新渲染时, SomeComponent 都会再次被调用。 React.memo then decides whether the underlying component needs to be re-run, or whether the values returned by the previous render can be re-used. React.memo然后决定是否需要重新运行底层组件,或者是否可以重用之前渲染返回的值。 If it does need to be re-run, then it'll run the original MyComponent .如果确实需要重新运行,那么它将运行原始的MyComponent

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM