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

89
Visualizações
using the data only AFTER useEffect

I have a react component (written with Typescript) as below.

In this component, I try to read the excel in which I have the data & then use the data for rendering the component

Since the data is not read before the useEffect is run, the menuData is initialized as a null.

Reading the data works fine & I have no error with menuData.

However, the line let meals = [...new Set(menuData.map((item: menuItem) => item.Meal))]; is throwing the error TypeError: menuData is undefined. I think this is because this line is executed when the menuData is still undefined (before the useEffect runs).

How to overcome this error? In other words, how to run let meals = [...new Set(menuData.map((item: menuItem) => item.Meal))]; AFTER useEffect has run?

I would like to keep this line outside of useEffect because there are many more array functions (map, filter...etc) that need to be performed on menuData array of objects.

export const CategoryItems = ({ toggled }: CategoryItemsProps) => {
  
const [menuData, setMenuData] = useState<menuData | undefined>(undefined);

   /*Code to read the excel with menu items once the page is loaded.
  The sheet will be read only once*/
  useEffect(() => {
    let url = "data.xlsx";
........
....
.....
      setMenuData(XLSX.utils.sheet_to_json(worksheet, { raw: true }));

  }, []);

 let meals = [...new Set(menuData.map((item: menuItem) => item.Meal))];

  return (
    <div className={`category-items ${toggled ? "theme-dark" : "theme-light"}`}>
.
.
.
    //additional code to render the component based on the variable `meals`
.
.
.
      </div>
    </div>
  );
};
about 4 years ago · Juan Pablo Isaza
2 Respostas
Responde à pergunta

0

Just initialize your state as an empty array already.

const [menuData, setMenuData] = useState<menuData>([]);

That should work!

about 4 years ago · Juan Pablo Isaza Relatório

0

Personally I like to exit the render stage if data is yet to come, no point in going any further as the setState inside the useEffect is going to cause another render anyway.

if (!menuData) return null;
let meals = [...new Set(menuData.map((item: menuItem) => item.Meal))];

null is just a simple way to render nothing..

What I like about this way of doing it, if you find useEffect can sometimes take some time, instead of returning null, we can maybe return some form of loading indicator..

if (!menuData) return <div className="loading">Loading..</div>;
let meals = [...new Set(menuData.map((item: menuItem) => item.Meal))];

Initialising the data to something empty works, but you kind of loose some implicit state, and if the structures your rendering are more complex, exiting early I find much easier to reason with..

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