Wrapper hell

Before Hooks, if we wanted to encapsulate state management logic, we had to use higher-order components and render props. For example, we create a React component that uses contexts to deal with user authentication as follows:

  1. We start by importing the authenticateUser function in order to wrap our component with the context, and the AuthenticationContext component in order to access the context:
import authenticateUser, { AuthenticationContext } from './auth'
  1. Then, we define our App component, where we make use of the AuthenticationContext.Consumer component and the user render prop:
const App = () => (
<AuthenticationContext.Consumer>
{user =>
  1. Now, we display different texts depending on whether the user is logged in or not:
                user ? `${user} logged in` : 'not logged in'

   Here, we used two JavaScript concepts:

    • A ternary operator, which is an inline version of the if conditional. It looks as follows: ifThisIsTrue ? returnThis : otherwiseReturnThis.
    • A template string, which can be used to insert variables into a string. It is defined with backticks (`) instead of normal single quotes ('). Variables can be inserted via the ${variableName} syntax. We can also use any JavaScript expressions within the ${} brackets, for example, ${someValue + 1}.
  1. Finally, we export our component after wrapping it with the authenticateUser context:
        }
</AuthenticationContext.Consumer>
)

export default authenticateUser(App)

In the previous example, we used the higher-order authenticateUser component to add authentication logic to our existing component. We then used AuthenticationContext.Consumer to inject the user object into our component through its render props.

As you can imagine, using many contexts will result in a large tree with many sub-trees, also called wrapper hell. For example, when we want to use three contexts, the wrapper hell looks as follows:

<AuthenticationContext.Consumer>
{user => (
<LanguageContext.Consumer>
{language => (
<StatusContext.Consumer>
{status => (
...
)}
</StatusContext.Consumer>
)}
</LanguageContext.Consumer>
)}
</AuthenticationContext.Consumer>

This is not very easy to read or write, and it is also prone to errors if we need to change something later on. Furthermore, the wrapper hell makes debugging hard, because we need to look at a large component tree, with many components just acting as wrappers.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.128.79.88