Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

246
Visualizações
React: Ways of passing component as a props

What is difference between these two way of passing component as props.

  1. Passing RepoMenu as it is:
<Fetch
  url={`https://api.github.com/users/${login}/repos`}
  renderSuccess={RepoMenu}
/>
  1. Wrapping the RepoMenu in a function
<Fetch
  url={`https://api.github.com/users/${login}/repos`}
  renderSuccess={({ data }) => <RepoMenu data={data} />}
/>

RepoMenu internally uses a custom hook.

function RepoMenu({ data, onSelect = (f) => f }) {
  const [{ name }, prev, next] = useIterator(data);

  return (
    <div style={{ display: "flex" }}>
      <button onClick={prev}>&lt;</button>
      <p>{name}</p>
      <button onClick={next}>&gt;</button>
    </div>
  );
}

Using one (Passing RepoMenu as it is) starts failing, React starts throwing an exception Rendered more hooks than during the previous render.

Initially i thought may it is not possible to use the component like the method 1. But to test it more further i created a small Pure Component and just tried to render the data passed to it.

function RepoMenuPure({ data = [], onSelect = (f) => f }) {
  return (
    <div style={{ display: "flex" }}>
      <h3>There are {data.length} repos for this user</h3>
    </div>
  );
}

And when i tried to use it like below, It worked in this case.

const UserRepositories = ({ login, selectedRepo, onSelect = (f) => f }) => {
  return (
    <Fetch
      url={`https://api.github.com/users/${login}/repos`}
      renderSuccess={RepoMenuPure}
    />
  );
};

Can someone please help me explain what is happening and what i am missing?

I have created a small sandbox here: https://codesandbox.io/s/stackoverflow-example-bqfn3e?file=/src/App.js

about 4 years ago · Juan Pablo Isaza
2 Respostas
Responde à pergunta

0

return renderSuccess({ data });

Your problem is you're calling a component like a function. Every time you call renderSuccess (which is RepoMenu - now it's not considered a component), it will trigger your custom hook useIterator which is invalid.

You can refer to this document

Don’t call Hooks inside loops, conditions, or nested functions.

Nested functions part is your current situation.

With the pure component, it was working because you didn't use any hooks, that's why you don't see any errors come out.

For the fix, you can do it this way

import React from "react";
import { useFetch } from "./hooks/useFetch";

function Fetch({
  url,
  loadingFallback = <div>Loading....</div>,
  errorFallback = <div>Some thing went wrong</div>,
  renderSuccess: RenderSuccess //introduce it as a component
}) {
  const { data, error, loading } = useFetch(url);

  if (loading) {
    return loadingFallback;
  }

  if (error) {
    return errorFallback;
  }

  if (data) {
    return <RenderSuccess data={data} />; //render a component instead of executing a function
  }

  return null;
}

export default Fetch;

Sandbox

about 4 years ago · Juan Pablo Isaza Relatório

0

In the first option :

renderSuccess={({ data }) => <RepoMenu data={data} />}

You are saying that Fetch component expects that renderSuccess receives a function that returns a Component. If you were using typescript, the type of renderSuccess in Fetch would be something like:

renderSuccess : (data: any) => JSX.Element

// OR return the component itself
renderSuccess : (data: any) => RepoMenu

And that´s why when you call renderSuccess({ data }) inside Fetch component works.

In the second option:

renderSuccess={RepoMenu}

You are saying that Fetch component expects that renderSuccess receives the RepoMenu Component (not a function). If you were using typescript, the type of renderSuccess in Fetch would be something like:

renderSuccess : JSX.Element

// OR the component itself
renderSuccess : RepoMenu

For this option work, you should change your Fetch component to something like this:

import React from "react";
import { useFetch } from "./hooks/useFetch";

function Fetch({
  url,
  loadingFallback = <div>Loading....</div>,
  errorFallback = <div>Some thing went wrong</div>,
  renderSuccess: Component
  //renderSuccess
}) {
  // console.log("renderSuccess", renderSuccess);

  const { data, error, loading } = useFetch(url);

  if (loading) {
    return loadingFallback;
  }

  if (error) {
    return errorFallback;
  }

  if (data) {
    // return renderSuccess({ data });
    return <Component data={data} />;
  }

  return null;
}

export default Fetch;
about 4 years ago · Juan Pablo Isaza Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda