简体   繁体   中英

React: Pass function property down to pure child component - Rerendering

I am new to React. I was reading about pure components ("Pure React" is that book I am reading) and came across this example that got me confused. The book says:

It's generally a bad idea to create newly define functions to pass into props like the code below. It's bad because passing a new function down to a pure component every time it renders means that it will always see “new” props, and therefore always re-render (needlessly). Avoid creating a new function in render when (a) the child component receiving the function prop is pure and (b) you expect the parent component to re-render often.

class App extends Component {
// ...
    renderContent() {
        switch(this.state.activeTab) {
           default:
           case 0: return <span>Items</span>;
           case 1: return <span>Cart</span>; 
        }
    }

    render() {
        let {activeTab} = this.state;
        return (
           <div className="App">
              <Nav activeTab={activeTab} onTabChange={this.handleTabChange} />
              <main className="App-content">
              {this.renderContent()}
              </main>
           </div>
    );
    }
}

const Nav = ({ activeTab, onTabChange }) => (
    <nav className="App-nav">
        <ul>
           <li className={`App-nav-item ${activeTab === 0 && 'selected'}`}>
              <a onClick={() => onTabChange(0)}>Items</a>
           </li>
           <li className={`App-nav-item ${activeTab === 1 && 'selected'}`}>
              <a onClick={() => onTabChange(1)}>Cart</a>
           </li>
        </ul>
    </nav>
);

I am confused because we are not passing a newly-defined function down to another React component. We are defining a new function on the "a" element's onClick property. So, for the code above, would we have extra re-renders that we don't want? It wouldn't re-render needlessly because I am not passing "() => onTabChange(1)" as a prop to a React pure child component, right?

Is the author of the book trying to make us imagine that there is a Pure React Component in place of the "a" element in the above code?

You are not passing a new arrow function on the Nav Component and it does not re-render because you are using the arrow function on the a element eventho use new functions on the element is a bad practice is not for that reason that the Nav is render is for the React behavior every time that you provide a props on a component it's render automatically, for prevent that you can use Pure component for Class component and memo for functional component here and example to avoid the re-render using memo:

const NavMemo = React.memo(({ activeTab, onTabChange }) => {
  console.log('Render');
  return (
    <nav className="App-nav">
      <ul>
        <li className={`App-nav-item ${activeTab === 0 && 'selected'}`}>
          <a onClick={() => onTabChange(0)}>Items</a>
        </li>
        <li className={`App-nav-item ${activeTab === 1 && 'selected'}`}>
          <a onClick={() => onTabChange(1)}>Cart</a>
        </li>
      </ul>
    </nav>
  );
});

The React doc is: https://reactjs.org/docs/react-api.html#reactmemo

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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