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

126
Visualizações
infinite loop using useEffect

so creating a project that updates me on my data in firebase however i have console logged the data and its constantly coming through. How do i stop the loop essentially so it doesn't crash.

import "./App.css";

import "semantic-ui-css/semantic.min.css";
import { Container, Divider, Card } from "semantic-ui-react";
import Header from "./components/Header";
import Cards from "./components/Cards/index";
import { useState, useEffect } from "react";
import { AppProvider } from "./Context/Context.js";
import "firebase/compat/auth";
import {} from "firebase/firestore";
import * as FirestoreService from "./components/service/firebase";
import firebase from "@firebase/app-compat";

function App() {
  const [user, setUser] = useState(null);
  const [cloudFucntions, setCloudFucntions] = useState();
  const [error, setError] = useState();

  useEffect(() => {
    firebase.auth().onAuthStateChanged((user) => {
      setUser(user);

      const unsubscribe = FirestoreService.getCloudFunctionItems(
        (querySnapshot) => {
          const updatedCloundFunctions = querySnapshot.docs.map((docSnapshot) =>
            docSnapshot.data()
          );
          setCloudFucntions(updatedCloundFunctions);
          console.log(updatedCloundFunctions);
        },
        (error) => setError("list-item-get-fail")
      );
      return unsubscribe;
    });
  }, [cloudFucntions]);

  return (
    <AppProvider>
      <div>
        <Container>
          <Header />

          <Divider horizontal section>
            Cloud Function Monitor
          </Divider>

          {user ? (
            <Card.Group itemsPerRow="4">
              {cloudFucntions &&
                cloudFucntions.map((cloudFunction) => {
                  return (
                    <Cards
                      key={cloudFunction.id}
                      cloudFunction={cloudFunction}
                    ></Cards>
                  );
                })}
            </Card.Group>
          ) : (
            <h2> Please sign in using the button in the top right. </h2>
          )}
        </Container>
      </div>
    </AppProvider>
  );
}

export default App;

Image of console...

I have tried using an empty array and not passing anything through however i get the errors: Warning: Each child in a list should have a unique "key" prop. Warning: Failed prop type: Invalid prop children supplied to CardContent, expected a ReactNode. Warning: Functions are not valid as a React child. This may happen if you return a Component instead of from render. Or maybe you meant to call this function rather than return it.

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

0

You can't generally use a dependency for an effect that the effect ultimately updates, this is what leads to render looping. For the useEffect hook, cloudFucntions isn't referenced at all in the callback, so it's not a dependnecy. With firebase connections it's more common to use a mounting useEffect hook, i.e. an empty dependency array.

I see also that the component doesn't unsubscribe from the onAuthStateChanged check. Since the the second cloud functions fetching doesn't appear to be dependent on the user, you should split these into their own effects and subscription clean ups.

useEffect(() => {
  const unsubscribe = firebase.auth()
    .onAuthStateChanged((user) => setUser(user));
  return unsubscribe;
}, []);

useEffect(() => {
  const unsubscribe = FirestoreService.getCloudFunctionItems(
    (querySnapshot) => {
      const updatedCloundFunctions = querySnapshot
        .docs
        .map((docSnapshot) => docSnapshot.data());
      setCloudFucntions(updatedCloundFunctions);
    },
    (error) => setError("list-item-get-fail")
  );
  return unsubscribe;
}, []);

Warning: Each child in a list should have a unique "key" prop.

This only means that key={cloudFunction.id} isn't a unique enough id to be used as a React key. React keys must be unique among siblings. Don't use the array index as key unless you've no other choice. It's not recommended.

If your cloud function objects have duplicate ids, or there are duplicate cloud functions being returned you should fix this in the backend. If this isn't something you can resolve in the backend then you'll need to generate unique ids when you receive them in the frontend.

Example:

import { v4 as uuidV4 } from 'uuid';

...

const updatedCloundFunctions = querySnapshot
  .docs
  .map((docSnapshot) => ({
    guid: uuidV4(), // <-- generate your own GUID
    ...docSnapshot.data(),
  }));
setCloudFucntions(updatedCloundFunctions);

...

cloudFucntions.map((cloudFunction) => {
  return (
    <Cards
      key={cloudFunction.guid} // <-- use your GUID here as key
      cloudFunction={cloudFunction}
    />
  );
})}
Warning: Failed prop type: Invalid prop children supplied to CardContent, expected a ReactNode.
Warning: Functions are not valid as a React child.

For each of these we'd need to see the Cards component I suspect. The warnings are with regard to a CartContent component it seems. You can add the Cards component and other relevant code, along with any propTypes definitions and we can further refine answer, or you can post a new question on SO since these are rather extra-curricular to the issue of the render looping and React keys.

about 4 years ago · Juan Pablo Isaza Relatório

0

You have an incorrect dependency on the useEffect. The call to setCloudFucntions will retrigger useEffect (because it sets cloudFucntions)

  useEffect(() => {
    ...
          setCloudFucntions(updatedCloundFunctions);
    ...
  }, [cloudFucntions]);

You don't need it, your effect does not use cloudFucntions.

The warning is concerning the key in the render, it seems that cloudFunction.id may not be unique.

You could do this

cloudFucntions.map((cloudFunction, idx) => {
  return (
    <Cards
      key={idx}
      cloudFunction={cloudFunction}
    ></Cards>
  )
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