Javascript 在将状态传递给我的useState钩子之后,它是未定义的,为什么?
我正在使用谷歌youtube api来流一些视频。不幸的是,当一个用户点击一个视频时,我在传递视频细节时被卡住了。 (我知道这个警告,我将很快通过在缩略图中添加索引来解决此问题) 问题是(它也在帖子的中间,但恐怕它会丢失):为什么HSS我的代码>搜索值。视频< /代码>改为未定义?< /P> 我得到了一个工作版本: 当我点击视频的缩略图时,我得到了预期的结果。 下面是它的代码: App.jsJavascript 在将状态传递给我的useState钩子之后,它是未定义的,为什么?,javascript,reactjs,react-hooks,Javascript,Reactjs,React Hooks,我正在使用谷歌youtube api来流一些视频。不幸的是,当一个用户点击一个视频时,我在传递视频细节时被卡住了。 (我知道这个警告,我将很快通过在缩略图中添加索引来解决此问题) 问题是(它也在帖子的中间,但恐怕它会丢失):为什么HSS我的代码>搜索值。视频< /代码>改为未定义?< /P> 我得到了一个工作版本: 当我点击视频的缩略图时,我得到了预期的结果。 下面是它的代码: App.js import React, { useState, createContext } from &quo
import React, { useState, createContext } from "react";
import NavBar from "./NavBar";
import youtube from "../apis/youtube";
import VideoList from "./VideoList";
import VideoDetail from "./VideoDetail";
export const VideoContext = createContext();
function App() {
const [ searchedValue, setSearchedValue ] = useState({ videos: [], selectedVideo: null });
const API_KEY = process.env.REACT_APP_API_KEY;
const handleSearch = async (inputText) => {
const response = await youtube.get("/search", {
params: {
q: inputText,
part: "snippet",
type: "video",
maxResults: 5,
key: API_KEY
}
});
setSearchedValue({ videos: response.data.items });
};
const handleSelectedVideo = (singleRenderedVideo) => {
console.log("from App.js: ", singleRenderedVideo);
// setSearchedValue({ selectedVideo: singleRenderedVideo });
};
return (
<div className="ui container">
<NavBar handleSearch={handleSearch} />
<VideoContext.Provider value={handleSelectedVideo}>
<p>I got {searchedValue.videos.length} results.</p>
{/* <VideoDetail video={searchedValue.selectedVideo} /> */}
<VideoList handleSelectedVideo={handleSelectedVideo} listOfVideos={searchedValue.videos} />
</VideoContext.Provider>
</div>
);
}
export default App;
我得到以下错误:
const handleSelectedVideo = (singleRenderedVideo) => {
// console.log("from App.js: ", singleRenderedVideo);
setSearchedValue({ selectedVideo: singleRenderedVideo });
};
整个App.js,其中的代码被更改
import React, { useState, createContext } from "react";
import NavBar from "./NavBar";
import youtube from "../apis/youtube";
import VideoList from "./VideoList";
import VideoDetail from "./VideoDetail";
export const VideoContext = createContext();
function App() {
const [ searchedValue, setSearchedValue ] = useState({ videos: [], selectedVideo: null });
const API_KEY = process.env.REACT_APP_API_KEY;
const handleSearch = async (inputText) => {
const response = await youtube.get("/search", {
params: {
q: inputText,
part: "snippet",
type: "video",
maxResults: 5,
key: API_KEY
}
});
setSearchedValue({ videos: response.data.items });
};
const handleSelectedVideo = (singleRenderedVideo) => {
// console.log("from App.js: ", singleRenderedVideo);
setSearchedValue({ selectedVideo: singleRenderedVideo });
};
return (
<div className="ui container">
<NavBar handleSearch={handleSearch} />
<VideoContext.Provider value={handleSelectedVideo}>
<p>I got {searchedValue.videos.length} results.</p>
<VideoDetail video={searchedValue.selectedVideo} />
<VideoList handleSelectedVideo={handleSelectedVideo} listOfVideos={searchedValue.videos} />
</VideoContext.Provider>
</div>
);
}
export default App;
import React,{useState,createContext}来自“React”;
从“/NavBar”导入导航栏;
从“./API/youtube”导入youtube;
从“/VideoList”导入视频列表;
从“/VideoDetail”导入VideoDetail;
export const VideoContext=createContext();
函数App(){
const[searchedValue,setSearchedValue]=useState({videos:[],selectedVideo:null});
const API_KEY=process.env.REACT_APP_API_KEY;
const handleSearch=async(inputText)=>{
const response=wait youtube.get(“/search”{
参数:{
问:输入文本,
部分:“片段”,
键入:“视频”,
最大结果:5,
密钥:API_密钥
}
});
setSearchedValue({videos:response.data.items});
};
const handleSelectedVideo=(singleRenderedVideo)=>{
//log(“from App.js:,singleRenderedVideo”);
setSearchedValue({selectedVideo:singleRenderedVideo});
};
返回(
我得到了{searchedValue.videos.length}结果
);
}
导出默认应用程序;
searchedValue设置为{selectedVideo:…}。另一个属性,因为新值没有该属性。设置searchedValue时,应包括视频属性。在类组件中应该设置searchedValue({…searchedValue,selectedVideo:newValue})如果设置状态并仅提供部分对象,react将与完整状态进行浅合并。这不会发生在功能组件中。不管你把状态设置成什么,那就是状态。所以这个代码:
setSearchedValue({ selectedVideo: singleRenderedVideo })
…将仅为具有selectedVideo属性的对象设置状态。它不再具有视频属性
您有两个选择:
非常感谢你的回答。但是,我还有一个关于#2的问题:在setSelectedVideo(singleRenderedVideo)中,您不使用selectedVideo的值。这样做可以吗?在您提供的代码中,新值与旧值无关,因此不需要使用旧值。如果您确实需要使用旧值(例如,因为您正在递增计数器),通常最好使用setState的函数版本,如
setCount(prevCount=>prevCount+1)
感谢您让我回到正确的方法。但是,在您的解决方案中,仅执行setSearchedValue({…searchedValue,selectedVideo:newValue})是不够的。Nicholas Tower使用setSearchedValue(previous=>({…previous,selectedVideo:singleRenderedVideo})提供的答案;作品
import React from "react";
import VideoItem from "./VideoItem";
const VideoList = ({ listOfVideos }) => {
const renderedListOfVideos = listOfVideos.map((video) => {
return <VideoItem singleRenderedVideo={video} />;
});
return <div className="ui relaxed divided list">{renderedListOfVideos}</div>;
};
export default VideoList;
const handleSelectedVideo = (singleRenderedVideo) => {
// console.log("from App.js: ", singleRenderedVideo);
setSearchedValue({ selectedVideo: singleRenderedVideo });
};
import React, { useState, createContext } from "react";
import NavBar from "./NavBar";
import youtube from "../apis/youtube";
import VideoList from "./VideoList";
import VideoDetail from "./VideoDetail";
export const VideoContext = createContext();
function App() {
const [ searchedValue, setSearchedValue ] = useState({ videos: [], selectedVideo: null });
const API_KEY = process.env.REACT_APP_API_KEY;
const handleSearch = async (inputText) => {
const response = await youtube.get("/search", {
params: {
q: inputText,
part: "snippet",
type: "video",
maxResults: 5,
key: API_KEY
}
});
setSearchedValue({ videos: response.data.items });
};
const handleSelectedVideo = (singleRenderedVideo) => {
// console.log("from App.js: ", singleRenderedVideo);
setSearchedValue({ selectedVideo: singleRenderedVideo });
};
return (
<div className="ui container">
<NavBar handleSearch={handleSearch} />
<VideoContext.Provider value={handleSelectedVideo}>
<p>I got {searchedValue.videos.length} results.</p>
<VideoDetail video={searchedValue.selectedVideo} />
<VideoList handleSelectedVideo={handleSelectedVideo} listOfVideos={searchedValue.videos} />
</VideoContext.Provider>
</div>
);
}
export default App;
setSearchedValue({ selectedVideo: singleRenderedVideo })
setSearchedValue(previous => ({
...previous,
selectedVideo: singleRenderedVideo
}));
const [ videos, setVideos ] = useState([]);
const [ selectedVideo, setSelectedVideo ] = useState(null);
// ...
setSelectedVideo(singleRenderedVideo);