reactjs - Inicializando con useState después de que UseEffect regrese: ¿Es eso posible?

CorePress2024-01-25  7

Tengo dos preguntas sobre React.

Usando useEffect estoy llamando a una API:

React.useEffect(() => {
  //API get call
},[]);

El resultado de la API se almacena en una matriz.

Pregunta 1: Sé que useEffect es un método asincrónico, pero ¿hay alguna forma de usar useState para inicializar los valores del menú desplegable después de que useEffect regrese?

Pregunta 2: ¿Cómo puedo inicializar los valores dentro de un bucle forEach con los valores de la matriz?

Claro, establece el estado en la devolución de llamada useEffect y estará disponible en el próximo renderizado.

- ggorlen

28 de marzo de 2021 a las 5:21



------------------------------------

Después de la llamada API en useEffect, llame al estado establecido para el estado de uso en el que está guardando. Por ejemplo:

const [state, setState] = useState([]);

const someFetch = async () => {
 // using JS fetch API
 const result = await fetch("getFetchSomeData");
 // assuming the state is in the form of an array
 setState(result.json())
}

useEffect(() => }{
   someFetch();
});

return (
  // rendering the array of fetched state this will update on next render after fetch
  <div>{state}</div>
):



------------------------------------

Pregunta 1

Probablemente haría algo como esto:

function MyComponent() {
  const [isLoading, setIsLoading] = useState(false);
  const [data, setData] = useState(undefined);
  
  useEffect(() => {
    async function getData() {
      setIsLoading(true);
      const data = await /* API call */
      setData((prevVal) => data);
      setIsLoading(false);
    }

    getData();
  }, []);
  
  if (loading) return <h1>Loading...</h1>;

  if (!loading && !data) return <h1>Error!</h1>;

  return (
    /* your component */
  );
}

En esencia, hay que jugar con la "asincronía" aspecto de los ganchos.

Pregunta 2

No dijiste qué deseas inicializar, pero supongo que un componente de algún tipo requiereSon los valores de la API. El siguiente ejemplo utiliza el elemento de selección HTML. Utilice mapa().

<select>
{
  data && data.map(({value, label}, index) => (
    <option key={index} value={value}>{label}</option>
  ))
}
</select>



------------------------------------

Pregunta 1: Sé que useEffect es un método asincrónico, pero ¿hay alguna forma de usar useState para inicializar los valores del menú desplegable después de que useEffect regrese?

No, no podemos inicializar useState después de que se ejecute useEffect. El gancho useEffect siempre se ejecuta después del primer renderizado y después de cada actualización. También necesitamos tener el valor inicializado para el estado en el primer renderizado. Luego, más tarde, cuando se ejecute useEffect, simplemente podremos actualizar el estado configurándolo.

function App(){

 const [stateVariable, setStateVariable] = useState(null);
 
 useEffect(() => {

   async function fetchApiCall(){
    fetch('http://example.com/movies.json')
       .then(response => response.json())
       .then(data => setStateVariable(data));
   }
  fetchApiCall(); // function call

 },[]);

}

Pregunta2: ¿Cómo puedo inicializar los valores dentro de un bucle forEach con los valores del array?

Ahora tenemos nuestros datos en nuestra variable de estado. Lo más probable es que los datos que provienen de la API estén en una matriz de objetos [JSON].

La función Array.prototype.map() puede ser útil aquí. Según los documentos de mdn,

El método map() crea una nueva matriz llena con los resultados de llamar a una función proporcionada en cada elemento de la matriz que llama.


function processEachElement(element, index){
  return <li key={index}>{element}</li>;
}

const newData = data.map(processEachElement);
// Now the newData is an array of `JSX.Elements`. Remember, not an array of objects.

entonces, el código final se proporciona a continuación,

function App() {
  const [stateVariable, setStateVariable] = useState(null);

  useEffect(() => {
    async function fetchApiCall() {
      fetch("http://example.com/movies.json")
        .then((response) => response.json())
        .then((data) => setStateVariable(data));
    }
    fetchApiCall(); // function call
  }, []);

  function processEachElement(element, index) {
    return <li key={index}>{element}</li>;
  }

  const newData = data.map(processEachElement);

  return <ul>{newData}</ul>;
}

Su guía para un futuro mejor - libreflare
Su guía para un futuro mejor - libreflare