Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

171
Views
¿Por qué mi aplicación ReactJs no se actualiza correctamente?

Estoy escribiendo una aplicación de libro de cocina. Las recetas del libro de cocina se almacenan en archivos yaml y estos se almacenan de forma estática. Cuando cargo el sitio, accederá automáticamente a un archivo index.json en el que se indexan todas las recetas y las cargará una tras otra y las agregará a una matriz. Luego, esta matriz se entrega al método setRecipe, donde debería actualizar el dom en consecuencia. esto no sucede Ya traté de console.log un poco y al hacer esto, registré los datos esperados, pero tan pronto como actualicé la página, este ya no es el caso. La solicitud de los archivos yaml se está realizando. ¿Por qué sucede eso?

Código fuente completo

 import React, { useState, useEffect } from 'react'; import jsyaml from 'js-yaml' import { ListGroup, ListGroupItem } from 'react-bootstrap'; const basePath = '/k0chbuch' const recipeStore = basePath + '/recipe-store' const index = recipeStore + '/index.json' const RecipeList = () => { const [recipes, setRecipes] = useState([]); useEffect(() => { fetchAllRecipes(); }, []); const fetchAllRecipes = () => { fetch(index) .then(response => { if (!response.ok) { throw new Error("HTTP error " + response.status); } return response.json() }) .then(recipeIndex => { let store = [] recipeIndex.forEach(element => { fetch(recipeStore + '/' + element + '.yaml') .then(res => res.blob()) .then(blob => blob.text()) .then(text => jsyaml.load(text)) .then(recipeObject => { store.push(recipeObject) }) }) return store }) .then((all) => setRecipes(all)); } return ( <div> <h1>Rezepte:</h1> <ListGroup> {recipes.map((r)=>(<ListGroupItem>{r.Titel}</ListGroupItem>))} </ListGroup> </div> ); }; export default RecipeList;

Ejemplo simple de Yaml:

 --- Titel: Hackbraten Autor: d3v3lop3r Komplexitaet: 1 Portionen: 4 Zutaten: - 1000g Hack - 150g Zwiebeln - Gewürze nach Wahl Zubereitung: | Zuerst wird das Hack gewürzt, dann die Zwiebeln braten und dem Hack zugeben. Kräftig kneten, dann bei 200°C eine Stunde backen. Kommentar: Schmeckt am besten mit Kartoffeln!
about 4 years ago · Juan Pablo Isaza
2 answers
Answer question

0

Su problema viene con llenar la matriz de la store en su segundo .then() : cuando use Array.prototype.forEach , recuerde que return realmente no hace nada. No está esperando que se analice el blob antes de resolver la promesa. De hecho, esta sección de las promesas encadenadas se resuelve inmediatamente :

 .then(recipeIndex => { let store = []; recipeIndex.forEach(element => { fetch(...); }); // `store` is returned immediately without waiting for forEach! return store; })

En su lugar, sugeriría usar Array.prototype.map para devolver una serie de promesas basadas en recipeIndex . Luego devuelva Promise.all() , lo que garantiza que todas las promesas se resuelvan:

 fetch(index) .then(response => { if (!response.ok) { throw new Error("HTTP error " + response.status); } return response.json(); }) .then(recipeIndex => { const promises = recipeIndex.map((element) => { return fetch(recipeStore + '/' + element + '.yaml') .then(res => res.blob()) .then(blob => blob.text()) .then(text => jsyaml.load(text)); }); return Promise.all(promises); }) .then((all) => setRecipes(all));

¿Qué pasa con el uso for bucle? (Puede, pero no recomendado)

Una alternativa es usar un bucle for , que luego puede usar async/await. Sin embargo, normalmente no sugeriría esto por dos razones:

  1. for loop + await significa que cada solicitud se envía una después de la otra y no en paralelo , lo que aumenta la latencia. La solución Array.prototype.map anterior envía solicitudes de búsqueda al mismo tiempo.
  2. algunos linters desalientan el anidamiento de devoluciones de llamada asíncronas dentro de .then()

Sin embargo, si quieres intentarlo, un bucle for es totalmente factible:

 fetch(index) .then(response => { if (!response.ok) { throw new Error("HTTP error " + response.status); } return response.json(); }) .then(async (recipeIndex) => { const recipes = []; for (const element of recipeIndex) { const recipe = await fetch(recipeStore + '/' + element + '.yaml') .then(res => res.blob()) .then(blob => blob.text()) .then(text => jsyaml.load(text)); recipes.push(recipe); } }) .then((all) => setRecipes(all));
about 4 years ago · Juan Pablo Isaza Report

0

useEffect se ejecuta en función de la matriz de dependencias que se pasa como segundo argumento del useEffect .

Prueba esto,

 const [recipes, setRecipes] = useState([]); useEffect(() => { if(!recipes && recipes.length == 0){ fetchAllRecipes(); } }, [recipes])

Esto hará que su gancho useEffect llame tan pronto como cambie el estado de las recipes , pero solo hará que la función fetchRecipes() llame si el estado de las recipes es null o la longitud de la matriz es 0

about 4 years ago · Juan Pablo Isaza Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!