What is "Prop Drilling"?

Asked

Viewed 1,265 times

7

I believe the term is related to passing properties between various components, but I don’t understand exactly.

What is "Prop Drilling"? How to avoid it? It is a common practice?

1 answer

9


What is the "Prop Drilling"?

Literally, it’s the "leak of props," it’s when you pass a props, from a father to a son, the son passes to his son, and so on. This generates a "leak of props", for example:

class Home extends React.Component {
  state = {
    usuario: { nome: 'Gandalf'},
  };

  render() {
    const { usuario } = this.state;
    return (
      <div>
        <PaginaUsuario
          usuario={usuario}
        />
      </div>
    );
  }
}

const PaginaUsuario = ({ usuario }) => {
  return (
    <div>
      <Titulo>Página do usuário</Titulo>
      <NomeUsuario usuario={usuario}/>
    </div>
  );
};

const NomeUsuario = ({ usuario }) => {
  return (
    <div>
      <p>Usuario: {usuario.nome}</p>
    </div>
  );
};

In the example above, "props Drilling" happens, you pass the user variable to whole tree, and some components do not need and do not use this props, in our case PaginaUsuário, the best in this case is if there was a way to pass variable directly from Home -> NomeUsuario.

How to avoid it?

There are three alternatives:

  • Redux, but is used in specific cases and when actually necessary, own experience, don’t use Redux if you don’t really need.

  • Context API and Render props, React itself offers tools to handle this.

Following the path of Context API, this would be our example above:

export const HomeContext = createContext({});

class Home extends React.Component {
  state = {
    usuario: { nome: 'Gandalf'},
  };

  render() {
    const { usuario } = this.state;
    return (
      <HomeContext.Provider>
        <PaginaUsuario
          value={{ usuario: usuario }}
        />
      </HomeContext.Provider>
    );
  }
}

const PaginaUsuario = () => {
  return (
    <div>
      <Titulo>Página do usuário</Titulo>
      <NomeUsuario/>
    </div>
  );
};

const NomeUsuario = ({ usuario }) => {
  return (
    <HomeContext.Consumer>
    {({ usuario }) => (
      <p>Usuario: {usuario.nome}</p>
    )}
    </HomeContext.Consumer>
  );
};

If you follow the path of Render props, this would be our initial example:

class Home extends React.Component {
  state = {
    usuario: { nome: 'Gandalf'},
  };

  render() {
    const { usuario } = this.state;
    return (
      <div>
        <PaginaUsuario
          renderItem={usuario => (
            <NomeUsuario
              usuario={usuario}
            />
          )}
        />
      </div>
    );
  }
}

const PaginaUsuario = ({ renderItem }) => {
  return (
    <div>
      <Titulo>Página do usuário</Titulo>
      <div>
        {renderItem()}
      </div>
    </div>
  );
};

const NomeUsuario = ({ usuario }) => {
  return (
    <div>
      <p>Usuario: {usuario.nome}</p>
    </div>
  );
};

It’s a common practice?

It is very common that this happens and should be avoided, because the composites end up getting very attached, not to mention that starts to repeat code and it is easy to appear bugs this way.

Refs:

Render Props - React

How to avoid Prop-Drilling in React

Context API - React

  • Very well explained!

  • Thus, for simple cases, that is, as in the example, the best solution is to use Context API?

Browser other questions tagged

You are not signed in. Login or sign up in order to post.