-
Notifications
You must be signed in to change notification settings - Fork 50.4k
Description
In our project, we often create components whose purpose is to constrain or enhance another component. We've run into a problem with this approach when a component needs to change how it's displayed based on some state.
For example, suppose we have an IconButton for a button that just contains an icon, and an ActionButton for one that shows text and an icon, and we want to switch a button between these two based on some state. Even though they both render a Button, React sees these as different components and re-creates the button itself when changing between them. If the button was in focus, it will lose focus from this state change.
My idea to solve this problem is to allow components to declare themselves an alias or wrapper for another component. During React's reconciliation, when comparing component types, components will match if they or any of their aliases match. Taking the example above, here's how the reconciliation will work:
| Existing component | New component | Matches as |
|---|---|---|
| IconButton | IconButton | IconButton |
| ActionButton | ActionButton | ActionButton |
| IconButton | ActionButton | Button |
| ActionButton | IconButton | Button |
| Button | (Icon/Action)Button | Button |
| (Icon/Action)Button | Button | Button |
To ensure that React will always be able to match components like this, a component that declares itself an alias must always return a single element of its aliased component (or null); otherwise React will report an error.