使用useEffect / useState的条件渲染,为什么在切换组件时DOM会有延迟?



简介/背景

我正在尝试使用React构建一个应用程序,允许基于所选菜单项的图像或视频显示。我目前使用WordPress内的高级自定义字段来构建我的数据对象,并使用graphQL将它们查询到我的项目中。

我希望应用程序显示视频组件或图像组件。这个选择将通过条件呈现和基于对象字段的内容来确定。

每个对象包含一个标题、一个图像字段和一个视频字段。如果有问题的条目应该显示为图像,则视频字段将设置为字符串'null'。无论如何,所有字段都将返回字符串。

我使用useState来瞄准一个特别活跃的字段,然而,尽管触发了状态的变化,条件呈现似乎并没有改变。

<<p>

应用程序/strong>这是我的方法

function Display({ objects }) {
const [setVisualOption, changeVisualOption] = useState(false);
const [appState, setState] = useState({
myObjects: objects,
activeTitle: "null",
activeImage: "null",
activeMediaUrl: "null",    
});
function toggleActive(index, trackIndex) {
setState({
...appState,
activeTitle: appState.myObjects[index].title,
activeImage: appState.myObjects[index].image[0].mediaItemUrl,
activeMediaUrl: appState.myObjects[index].mediastreamurl,
});
changeVisualOption(appState.activeImage.includes("null"));
}
useEffect(() => {}, [
appState.activeTitle,
appState.activeImage,
appState.activeMediaUrl,
setVisualOption,
]);
return (
<div className="display">
<div className="list-box-right>
{appState.myObjects.map((element, index) => (
<>
<div
key={index}
className="menu-item"
onClick={() => {
toggleActive(index);
}}
>
{element.title}
</div>
</>
))}
</div>
<div className="right-grid">
{setVisualOption ? (
<VideoComponent activeImage={appState.activeImage}></VideoComponent>
) : (
<ImageComponent activeImage={appState.activeImage}></SingleImage>
)}
</div>
</div>
);
}

summary, to组件将objects作为prop,该prop是从另一个进行graphQL查询的组件传递下来的。然后,我将useState的初始值设置为对象,并将activeTitle, activeImage和activeMediaUrl设置为空。

然后,我使用一个函数,根据在返回语句中单击的索引,使用setState修饰符切换活动项。从那里我使用setVisualOption和评估activeImage是否包含'null' (null.jpg),如果这是真的,setVisualOption将被设置为true,允许视频组件被渲染

要清楚,没有产生错误,问题是一个轻微的呈现问题,需要双击才能改变状态并触发第三操作符的正确响应。

问题在条件渲染中。如果我把所有图像和对象字段只返回图像组件没有问题,和状态变化可以看出视觉注册为你点击选项列出。

只有当我引入条件渲染时才会有延迟,第一次单击不会从我试图显示的组件生成正确的响应,但是第二次单击会触发正确的响应。

正如你所看到的,我也在使用useEffect来尝试触发渲染响应,当任何描述的状态改变,但仍然遇到相同的问题。

有人知道这个bug的原因是什么吗?当查看setVisualOption的console.log时,它在第一次点击时没有显示为true。

如果你有什么建议就太好了,谢谢

你设置你的视觉选项设置appState之后,这就是为什么在changeVisualOptionappState.activeImage不是因为状态更新在更新的反应是异步的。当appState更改时,您可以使用useEffect来更新视觉选项,也可以在changeVisualOption

中使用appState.myObjects[index].image[0].mediaItemUrl
function toggleActive(index, trackIndex) {
setState({
...appState,
activeTitle: appState.myObjects[index].title,
activeImage: appState.myObjects[index].image[0].mediaItemUrl,
activeMediaUrl: appState.myObjects[index].mediastreamurl,
})
changeVisualOption(appState.myObjects[index].image[0].mediaItemUrl.includes("null"))
}

useEffect(() => {
changeVisualOption(appState.activeImage.includes("null"))
}, [appState])