reactjs 当依赖此数据的组件在没有占位符的情况下引发错误时,如何将State设置为空?

ut6juiuv  于 2022-11-29  发布在  React
关注(0)|答案(3)|浏览(164)

问题概述:

1.使用Homepage.js、Sidebar.js组件和Project.js组件构建个人网站。
1.项目组件从对象的项目列表数组Map到主页上。
1.单击项目组件时,Sidebar.js组件将打开并显示活动项目信息。

  1. App.js具有activeProject状态,默认设置为列表中的第一个项目,因此边栏不会抛出错误。
    1.最终结果是边栏在项目单击时显示正确的项目标题、信息和视频源(检查模式),但视频本身是错误的,始终显示App.js上占位符的视频集
    Props passes right info, wrong video

详细数据:

在我的App.js中,我将activeProject设置为列表中的第一个项目作为默认值,通过它的标题。

const [activeProject, setActiveProject] = useState(ListOfProjects[0].title);

  return (
    <div className="App">
      <Navigation />
      <HomePage 
        isOpen={isOpen}
        setIsOpen={setIsOpen}
        activeProject={activeProject}
        setActiveProject={setActiveProject}
      />
      <Sidebar
        isOpen={isOpen}
        setIsOpen={setIsOpen}
        activeProject={activeProject}
      />
      <Footer />
    </div>
  );

我的项目在我的Homepage.js上进行了规划

<div className="project-list">
        {ListOfProjects.map((obj) => (
               <ProjectItem
                      key={obj.id}
                      title={obj.title}
                      video={obj.video}
                      videoAlt={obj.videoAlt}
                      liveLink={obj.liveLink}
                      codeLink={obj.codeLink}
                      isOpen={isOpen}
                      setIsOpen={setIsOpen}
                      activeProject={activeProject}
                      setActiveProject={setActiveProject}
               />
        ))}
</div>

每个项目组件都有一个click事件,用于打开侧栏组件,其中包含基于所单击项目标题得额外项目信息.

const showSidebar = () => {
        setActiveProject(title);
        setIsOpen(!isOpen);
}

在Sidebar.js上,我有一个从项目中提取的道具列表,其标题与当前活动的项目集状态相匹配。

const {title, liveLink, codeLink, video, videoAlt, tags, details, challenges, lessons} = ListOfProjects.find((project) => {
        return project.title === activeProject;
});

结果是侧边栏组件在检查工具中显示正确的标题、项目信息,甚至是正确的视频源,但项目视频总是列表中的第一个项目。

我尝试过的方法:

我尝试将App.jsactiveProject状态占位符更改为第二个项目。

const [activeProject, setActiveProject] = useState(ListOfProjects[1].title);

这导致边栏显示正确的项目标题、信息和视频源(检查模式),但现在视频始终显示第二个项目的视频。
然后我尝试将App.js activeProject状态占位符更改为“”

const [activeProject, setActiveProject] = useState("");

但这会导致边栏中出现错误。

Sidebar.js:15 Uncaught TypeError: Cannot destructure property 'title' of '_Projects_listOfProjects__WEBPACK_IMPORTED_MODULE_2__.default.find(...)' as it is undefined
avwztpqn

avwztpqn1#

试试看,如果the find找不到数据,它可能会返回undefined。所以你不能析构undefined。添加|| {}会检查ListOfProjects.find((project) => { return project.title === activeProject; })是否未定义,它会变成一个空对象{}

const {title, liveLink, codeLink, video, videoAlt, tags, details, challenges, lessons} = ListOfProjects.find((project) => {
        return project.title === activeProject;
}) || {};
7tofc5zh

7tofc5zh2#

只需创建默认项目

const defaultProject = {
title: "",
liveLink: "",
}
const {title, liveLink, codeLink, video, videoAlt, tags, details, challenges, lessons} = ListOfProjects.find((project) => {
        return project.title === activeProject;
}) || defaultProject;

此外,请确保title是唯一的,否则.find将返回错误的项目。

zengzsys

zengzsys3#

我想问题不在于你把数据传递给组件的方式,问题在于,当你重新呈现你的组件时,它会改变你的视频<source />标签中的src,但它实际上并没有重新加载视频,因此,即使使用正确的URL,您也会看到一个旧的或错误的视频。我建议在每次调用显示视频的子组件时使用load()。例如,每当视频源更改时,在useEffect中调用load:

useEffect(() => {
    document.querySelector("video").load();
}, [])

这将强制video重新加载新的src
编辑:
我克隆了你的项目,问题确实是用新的源代码重新加载视频。下面是解决方案。在你的Sidebar.js中添加下面的useEffect,并将className="sidebar-video"添加到你的<video />标记中。这样就可以了。

useEffect(() => {
    document.querySelector(".sidebar-video").load();
}, [title]);

相关问题