En mi componente de reacción existente, necesito renderizar otro componente de reacción durante un período de tiempo específico. Tan pronto como el componente principal se monte o se carguen los datos, el nuevo componente (o el componente secundario) debería estar visible después de 1 o 2 segundos y luego, después de otros pocos segundos, el nuevo componente debería estar oculto. Esto debe hacerse solo si no hay datos disponibles.
Esto es lo que actualmente he tratado de lograr:
import React, { useState, useEffect } from "react"; function App() { const [showComponent, setShowComponent] = useState(false); const sampleData = []; useEffect(() => { if (sampleData.length === 0) { setTimeout(() => { setShowComponent(true); }, 1000); } }, [sampleData]); useEffect(() => { setTimeout(() => { setShowComponent(false); }, 4000); }, []); const componentTwo = () => { return <h2>found error</h2>; }; return <>First component mounted{showComponent && componentTwo()}</>; } export default App;La implementación actual no está funcionando como se esperaba. El nuevo componente se renderiza en forma de parpadeo.
Aquí está el fragmento de trabajo adjunto:
¡Cualquier ayuda para resolver esto es apreciada!
Cada vez que la aplicación se renderiza, crea una nueva matriz sampleData . Puede ser una matriz vacía cada vez, pero es una matriz vacía diferente . Dado que es diferente, useEffect debe volver a ejecutarse cada vez, lo que significa que después de cada procesamiento, establece un tiempo de espera para que se apague en 1 segundo y muestre el componente.
Si esto es solo una matriz simulada que nunca cambiará, muévala fuera de la aplicación para que solo se cree una vez:
const sampleData = []; function App() { // ... }O bien, puede convertirlo en un valor de estado:
function App() { const [showComponent, setShowComponent] = useState(false); const [sampleData, setSampleData] = useState([]); // ... }He modificado el código para que funcione, espero que así sea como esperas que funcione .
import React, { useState, useEffect } from "react"; const sampleData = []; // this has to be out side or passed as a prop /* reason: when the component render (caued when calling setShowComponent) a new reference is created for "sampleData", this cause the useEffect run every time the component re-renders, resulting "<h2>found error</h2>" to flicker. */ function App() { const [showComponent, setShowComponent] = useState(false); useEffect(() => { if (sampleData.length === 0) { const toRef = setTimeout(() => { setShowComponent(true); clearTimeout(toRef); // it is good practice to clear the timeout (but I am not sure why) }, 1000); } }, [sampleData]); useEffect(() => { if (showComponent) { const toRef = setTimeout(() => { setShowComponent(false); clearTimeout(toRef); }, 4000); } }, [showComponent]); const componentTwo = () => { return <h2>found error</h2>; }; return <>First component mounted{showComponent && componentTwo()}</>; } export default App;Puede probar esto para la representación condicional.
import { useEffect, useState } from "react"; import "./styles.css"; const LoadingComponent = () => <div>Loading...</div>; export default function App() { const [isLoading, setLoading] = useState(true); const [isError, setIsError] = useState(false); const onLoadEffect = () => { setTimeout(() => { setLoading(false); }, 2000); setTimeout(() => { setIsError(true); }, 10000); }; useEffect(onLoadEffect, []); if (isLoading) { return <LoadingComponent />; } return ( <div className="App"> {isError ? ( <div style={{ color: "red" }}>Something went wrong</div> ) : ( <div>Data that you want to display</div> )} </div> ); }