Javascript 反应-显示隐藏两个元素,页面加载时不闪烁
编辑。我重新编写了代码,使其更加简约。下面的代码是对我的问题的尖峰测试 以下是该问题的视频: 我有两个部分 第一个组件名为TextEditor(它是一个文本编辑器),但是它的内容是不相关的——这个组件可以是任何东西。一个带有文本的简单div也同样重要 下一个组件名为Workflows,用于呈现IndexDB中的集合(使用Dexie.js库)。我将此集合命名为“workflows”,并且将其存储在其中的状态变量命名为Javascript 反应-显示隐藏两个元素,页面加载时不闪烁,javascript,reactjs,asynchronous,indexeddb,dexie,Javascript,Reactjs,Asynchronous,Indexeddb,Dexie,编辑。我重新编写了代码,使其更加简约。下面的代码是对我的问题的尖峰测试 以下是该问题的视频: 我有两个部分 第一个组件名为TextEditor(它是一个文本编辑器),但是它的内容是不相关的——这个组件可以是任何东西。一个带有文本的简单div也同样重要 下一个组件名为Workflows,用于呈现IndexDB中的集合(使用Dexie.js库)。我将此集合命名为“workflows”,并且将其存储在其中的状态变量命名为workflows\u list\u array 我想做的是: 加载页面时,我想
workflows\u list\u array
我想做的是:
加载页面时,我想检查是否有任何工作流具有特定ID。如果有,我将它们存储在工作流列表数组中并渲染它们。这部分我不需要帮助
但是,如果不存在具有上述条件的工作流,我希望隐藏名为workflows的组件,并呈现名为TextEditor的组件。如果工作流确实存在,我希望文本编辑器隐藏并显示工作流
问题是,即使我让它工作,当工作流确实存在时(当工作流\u列表\u数组填充时),文本编辑器在隐藏之前会短暂“闪烁”,然后显示工作流组件
我知道这是一个异步问题,但我不知道如何修复它
我在下面发布了代码,并试图将其控制在最低限度
Test.js
import React, {useState, useEffect} from "react";
import db from "../services"
function Workflows(props){
return (
<div>
<ul>
{
props.workflows.map((val,index)=>{
return <li key={index}>{val.content}</li>
})
}
</ul>
</div>
)
}
function TextEditor(){
return (
<div> TextEditor </div>
)
}
function Test(props){
let [workflows_list_array, set_state_of_workflows_list_array] = useState([]);
let [client_id_number, set_client_id_number] = useState(5);
useEffect(() => { // get all workflows of the selected client per its ID
db.workflows.toArray((workflows_list)=>{ // iterate through workflows array
return workflows_list
}).then((workflows_list)=>{
workflows_list.forEach((val)=>{
if(client_id_number === val.client_id){
set_state_of_workflows_list_array((prev)=>{
return [...prev, val]
});
}
});
});
}, []);
return(
<div>
{workflows_list_array.length ? null : <TextEditor/> }
{workflows_list_array.length ? <Workflows workflows={workflows_list_array}/> : null}
</div>
)
}
export default Test
import Dexie from 'dexie';
import 'dexie-observable';
var workflowMagicUserDB = new Dexie("WorkflowMagicUserDB");
workflowMagicUserDB.version(1).stores({
user: "",
workflows: "++id,client_id,content,title",
clients: "++id,name",
calendar_events: "++id,start,end,title"
});
export default workflowMagicUserDB
为什么不包括一个标志,指示您是否已经从IndexDB获得了数据,比如:
function Test(props){
const [loading, setLoading] = React.useState(true);
let [workflows_list_array, set_state_of_workflows_list_array] = useState([]);
let [client_id_number, set_client_id_number] = useState(5);
useEffect(() => {
db.workflows.toArray((workflows_list)=>{
}).then((workflows_list)=>{
}).finally(() => setLoading(false)); //when process finishes, it will update the state, at that moment it will render TextEditor or Workflows
}, []);
if(loading) return <LoadingIndicator/>; // or something else which indicates the app is fetching or processing data
return(
<div>
{workflows_list_array.length ? null : <TextEditor/> }
{workflows_list_array.length ? <Workflows workflows={workflows_list_array}/> : null}
</div>
)
}
export default Test
功能测试(道具){
常量[loading,setLoading]=React.useState(true);
让[workflows_list_array,set_state_of_workflows_list_array]=useState([]);
让[client\u id\u number,set\u client\u id\u number]=useState(5);
useffect(()=>{
db.workflows.toArray((工作流列表)=>{
})。然后((工作流列表)=>{
}).finally(()=>setLoading(false));//当进程完成时,它将更新状态,此时它将呈现TextEditor或工作流
}, []);
if(loading)return;//或指示应用程序正在获取或处理数据的其他内容
返回(
{工作流\列表\数组.length?空:}
{workflows\u list\u array.length?:null}
)
}
导出默认测试
当流程完成时,将执行
最终
,并将加载
状态设置为false,然后,你的应用程序将呈现文本编辑器
或工作流
,如果你试图有条件地呈现它们,并且一次呈现其中一个,那么你可以使用一个bool state值而不是两个。我这样做是因为我忽略了一些涉及更多条件的未来打算。我不想用不必要的细节使这篇文章停滞不前。我会再看一看,看看我是否可以摆脱或重构一些东西。我可能会在发布之前删除一些东西,这会让它变得更加混乱。@SouvikGhosh在我这方面,我按照您提到的方式重构了JSX呈现条件,我得到了相同的问题,因此就问题的根源而言,我不确定这有多重要。我认为您在useEffect中更新的workflowsExist
是异步的。尝试类似于{current\u workflows\u arr.length?:null}
的方法,而不是{show\u editor\u bool?:null}
。另外,请检查当前\u工作流\u arr.length
是否具有预期值。我也遇到了同样的问题。我要试一试。我忘了处理这个问题的默认方法是用加载程序屏幕隐藏它。
的闪烁非常糟糕,我研究并试图为您找到解决方案,但没有运气。但是,重新考虑一下,您现在想要的是您的组件
必须知道数据是否为空,它不能。因此,我认为要解决您的问题,您应该在UI设计中采用另一种方法。希望这有帮助。@dqlgnoleht那没有帮助。我只想在加载时列表为空时显示一个组件。如果不为空,则显示另一个组件。要做到这一点,我不必重新考虑我的用户体验。这项技术应该能够做到这一点