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

343
Visualizações
React hooks: call component as function vs render as element

Say we have component:

let Component = (props)=><div>Hi</div>;

I have sometimes come across code where someone calls a react component as function in render:

 const App = () => (
     <div> {Component()} </div>
 )

vs rendering it as element

 const App = () => (
     <div> <Component/> </div>
 )

In react hooks, what are possible drawbacks of calling component as function?


There is similar question but it is not specifically targeted at hooks - also that question is more about performance.

over 4 years ago · Santiago Trujillo
1 Respostas
Responde à pergunta

0

Here are some implications of calling component as function vs rendering it as element.

  1. Potential violation of rules of hooks

When you call a component as a function (see TestB() below) and it contains usage of hooks inside it, in that case react thinks the hooks within that function belongs to the parent component. Now if you conditionally render that component (TestB()) you will violate one of the rules of hooks. Check the example below, click the re-render button to see the error:

Error: Rendered fewer hooks than expected. This may be caused by an accidental early return statement.

 
function TestB() {
  let [B, setB] = React.useState(0);
  return (
    <div
      onClick={() => {
        setB(B + 1);
      }}
    >
      counter B {B}
    </div>
  );
}
 

function App() {
  let [A, setA] = React.useState(0);

  return (
    <div>
      <button
        onClick={() => {
          setA(A + 1);
        }}
      >
        re-render
      </button>
      {/* Conditionally render TestB() */}
      {A % 2 == 0 ? TestB() : null}
    </div>
  );
}
ReactDOM.render(
  <App />,
  document.getElementById("react")
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.1/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.1/umd/react-dom.production.min.js"></script>
<div id="react"></div>

Now you can use <TestB/> instead and see the difference.

  1. Reconciliation might not work as expected

When you render a react component as react element say <TestB/> and then on next render you render some different component <TestC/> instead of it (in the same place in component hierarchy), due to reconciliation algorithm (and since component type has changed), react will unmount <TestB/> component (all its state will be gone) and mount a new component <TestC/> instead.

If you call it as function however (e.g. TestB()), the component type will not participate in reconciliation anymore and you might not get expected results:

function TestB() {    
  return (
    <div     
    >
      <input/>
    </div>
  );
}
function TestC() {
  console.log("TestC")
  return (
    <div     
    >
      <input/>
    </div>
  );
}

function App() {
  let [A, setA] = React.useState(0);

  return (
    <div>
      <button
        onClick={() => {
          setA(A + 1);
        }}
      >
        re-render
      </button>
      {/*  Here we are alternating rendering of components */}
      {A % 2 == 0 ? TestB() : TestC()} 
    </div>
  );
}

ReactDOM.render(
  <App />,
  document.getElementById("react")
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.1/umd/react.production.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.1/umd/react-dom.production.min.js"></script>
    <div id="react"></div>

  • Type something in the input
  • Now click the re-render button
  • You can see now from the log that component TestC was rendered, but the input shows the same value you typed before - which might not be what you want as you rendered a different component. This happened because reacts reconciliation algorithm couldn't detect that we moved to a different component (from TestB to TestC) and didn't remove previous input instance from DOM.

Render these components as elements now (<TestB/> and <TestC/>) to see the difference.

over 4 years ago · Santiago Trujillo 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