Advanced React Patterns

Big Head
  • 👀 View the deployed code on Github.
  • Not happy with the solution? 🐞🐛 Suggest a change.
  • Grammar errors? ✏️ Edit this page.

Control Props, I

Summary: The control props pattern lets the user of a component manage that components state from the outside. Write a very simple button component that implements the bare minimum of this pattern.

Create a very simple component that has a buttonand also displays its internal state. The initial state should be {count: 0}. By default, the button increments its count by one when it is clicked. This component should be controllable from the outside. The user could control how the state is updated each time the component is clicked.

Say from the outside say you want to use this same button but instead:

  1. The counter starts at {count: 1}
  2. You'd rather double the value at each click.
  3. You also want to display the previous count value, and the "suggested" value, the value that would have been if we weren't controlling this component.
  4. You might also want the button to reset when it reaches a particular maximum value.

Here's an example api of how might want to use it. Whenever the state of the component changes, it will pass the suggestedState and the action that happened to the function we passed to onChange. And you can do whatever you want with that information to get the new state which you will pass back to the component.

My Solution

The component MyButtonWithStateDisplay could be using a hook useMyButtonWithStateDisplay. It could use the prop collections pattern! The hook is responsible for returning the actual state and the props that you should pass to the button given the optional onChange handler and controlled state passed to the component if any.

The useMyButtonWithStateDisplay hook may be using a reducer like this:

What we want the hook to do:

  1. The hook should return the new state of this component and the buttonProps that the component passes to its button. The buttonProps contains the props that the button needs, so that the behavior we want will be executed onClick.

  2. If we don't pass a controlledState , onClick will do the default behavior. When controlledState is passed to it, onClick will execute the onChange function, by passing the suggestedChange (default behavior result) and the action that happened to this onChange function.

Here's how we could write the hook: