仅反应渲染组件几秒钟
React render component only for few seconds
在我现有的反应组件中,我需要在特定时间段内渲染另一个反应组件。
一旦父组件 mounts/or 数据加载,新组件(或子组件)应该在 1-2 秒后可见,然后再过几秒,新组件应该隐藏。只有在没有可用数据时才需要这样做。
这是我目前努力实现的目标:
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;
当前的实现没有按预期工作。新组件以闪烁方式呈现。
附上工作片段:
感谢任何解决此问题的帮助!
每次 App 渲染时,您都会创建一个全新的 sampleData
数组。可能每次都是一个空数组,但它是一个不同的空数组。由于不同,useEffect 每次都需要重新运行,这意味着在每次渲染后,您设置超时以在 1 秒内关闭并显示组件。
如果这只是一个永远不会改变的模拟数组,那么将它移到 App 之外,这样它只创建一次:
const sampleData = [];
function App() {
// ...
}
或者,你可以把它变成一个状态值:
function App() {
const [showComponent, setShowComponent] = useState(false);
const [sampleData, setSampleData] = useState([]);
// ...
}
我已经修改了代码,希望它能像您期望的那样工作。
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;
You can try this for conditional rendering.
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>
);
}
在我现有的反应组件中,我需要在特定时间段内渲染另一个反应组件。 一旦父组件 mounts/or 数据加载,新组件(或子组件)应该在 1-2 秒后可见,然后再过几秒,新组件应该隐藏。只有在没有可用数据时才需要这样做。
这是我目前努力实现的目标:
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;
当前的实现没有按预期工作。新组件以闪烁方式呈现。
附上工作片段:
感谢任何解决此问题的帮助!
每次 App 渲染时,您都会创建一个全新的 sampleData
数组。可能每次都是一个空数组,但它是一个不同的空数组。由于不同,useEffect 每次都需要重新运行,这意味着在每次渲染后,您设置超时以在 1 秒内关闭并显示组件。
如果这只是一个永远不会改变的模拟数组,那么将它移到 App 之外,这样它只创建一次:
const sampleData = [];
function App() {
// ...
}
或者,你可以把它变成一个状态值:
function App() {
const [showComponent, setShowComponent] = useState(false);
const [sampleData, setSampleData] = useState([]);
// ...
}
我已经修改了代码,希望它能像您期望的那样工作。
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;
You can try this for conditional rendering.
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>
);
}