Jamie Kudla
Jamie Kudla

Reputation: 872

React Hooks function component with controlled rendering based on state/prop values

One of the benefits of being able to use shouldComponentUpdate on a React Class component is the ability to control the render based on a condition rather than just a change in state/prop values.

What is the preferred way to make this optimization using react hooks in a function component?

In the example below, the class component does not re-render if it is (or is staying) in a closed state, even if it has new children.

class DrawerComponent extends React.Component {
  static propTypes = {
    children: PropTypes.any,
  }

  state = {
    isOpen: false,
  }

  // only re-render if the drawer is open or is about to be open.
  shouldComponentUpdate(nextProps, nextState) {
    return this.state.isOpen || nextState.isOpen;
  }

  toggleDrawer = () => {
    this.setState({isOpen: !this.state.isOpen});
  };

  render() {
    return (
      <>           
        <div onClick={this.toggleDrawer}>
          Drawer Title
        </div>
        <div>
          {this.state.isOpen ? this.props.children : null}
        </div>
      </>
    )
  }
}

Function component counterpart (without optimization):

function DrawerComponent({ children }) {
  const [isOpen, setIsOpen] = useState(false);

  function toggle() {
    setIsOpen(!isOpen);
  } 

  return (
    <>
      <div onClick={toggle}>
        Drawer Title
      </div>
      <div>{isOpen ? children : null}</div>
    </>
  );
}

Upvotes: 0

Views: 1419

Answers (1)

Joru
Joru

Reputation: 4436

In this example, in my opinion there's no need for a shouldComponentUpdate optimization. It will already be fast since you're not rendering the children when the drawer is closed. The cost of running the functional component will be fairly negligible.

That said, if you did want to implement the equivalent behavior in a functional component, you could use React.memo and supply a custom areEqual function: https://reactjs.org/docs/react-api.html#reactmemo.

Upvotes: 2

Related Questions