我正在使用google youtube api播放一些视频。不幸的是,当用户单击视频时,我无法传递视频详细信息。 (我知道该警告,将会通过在缩略图中添加索引来尽快解决此问题。)
问题是(它也在帖子的中间,但恐怕会丢失):为什么将我的searchedValue.videos
更改为undefined?
这是它的代码:
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;
NavBar.js
import React, { useState } from "react";
const NavBar = (props) => {
const [ inputText, setInputText ] = useState("");
const handleSearch = (event) => {
props.handleSearch(inputText);
event.preventDefault();
};
const handleChange = (event) => {
setInputText(event.target.value);
};
return (
<div className="search-bar ui segment">
<form onSubmit={handleSearch} className="ui form">
<div className="field">
<label>Video Search</label>
<input
type="text"
placeholder="Type in to search for videos"
onChange={handleChange}
value={inputText}
/>
</div>
</form>
</div>
);
};
export default NavBar;
VideoDetail.js
import React from "react";
const VideoDetail = ({ video }) => {
if (!video) {
return <div>Loading...</div>;
}
return <div>{video.snippet.title}</div>;
};
export default VideoDetail;
VideoItem.js
import "./VideoItem.css";
import React, { useContext } from "react";
import { VideoContext } from "./App";
const VideoItem = ({ singleRenderedVideo }) => {
const videoContext = useContext(VideoContext);
return (
<div onClick={() => videoContext(singleRenderedVideo)} className="video-item item">
<img className="ui image" src={singleRenderedVideo.snippet.thumbnails.medium.url} alt="img" />
<div className="content">
<div className="header">{singleRenderedVideo.snippet.title}</div>
</div>
</div>
);
};
export default VideoItem;
VideoList.js
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;
但是在App.js中,当我尝试设置selectedVideo
的状态时:
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;
答案 0 :(得分:1)
在类组件中,如果设置状态并仅提供部分对象,则react将与完整状态进行浅表合并。在功能组件中不会发生这种情况。无论您将状态设置为什么,那就是状态。所以这段代码:
setSearchedValue({ selectedVideo: singleRenderedVideo })
...仅将状态设置为具有selectedVideo属性的对象。它不再具有视频属性。
您有两个选择:
setSearchedValue(previous => ({
...previous,
selectedVideo: singleRenderedVideo
}));
const [ videos, setVideos ] = useState([]);
const [ selectedVideo, setSelectedVideo ] = useState(null);
// ...
setSelectedVideo(singleRenderedVideo);
答案 1 :(得分:0)
searchedValue设置为{selectedVideo:...}。另一个属性,因为新值不具有该属性。设置searchedValue时,应包括您的视频属性。应该设置为setSearchedValue({... searchedValue,selectedVideo:newValue})