после передачи состояния моему хуку useState оно не определено, почему? - PullRequest
0 голосов
/ 21 июня 2020

Я использую google youtube api для потоковой передачи видео. К сожалению, я застрял при передаче деталей видео, когда пользователь нажимает на видео. (Я знаю об этом предупреждении, скоро исправлю это, добавив индекс к миниатюре).

Вопрос в том (он тоже находится в середине сообщения, но боюсь, что он получит lost): почему hss my searchedValue.videos изменился на undefined?

У меня рабочая версия: когда я нажимаю на эскиз видео, я получаю ожидаемый результат. picture of my working version

Here is the code for it:

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 (
         Я получил результаты {searchValue.videos.length}.  {/ * * /} ); } экспортировать приложение по умолчанию; 

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;

Список видео. 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;

Но в приложении. js, когда я пытаюсь установить состояние selectedVideo:

const handleSelectedVideo = (singleRenderedVideo) => {
        // console.log("from App.js: ", singleRenderedVideo);
        setSearchedValue({ selectedVideo: singleRenderedVideo });
    };

, я получаю следующую ошибку:

not working version

The whole App.js, where the code is changed.

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 (
         Я получил результаты {searchValue.videos.length}.  ); } экспортировать приложение по умолчанию; 

Ответы [ 2 ]

1 голос
/ 21 июня 2020

В компонентах класса, если вы установите состояние и предоставите только частичный объект, react будет выполнять неглубокое слияние с полным состоянием. Этого не происходит в функциональных компонентах. Что бы вы ни установили для состояния, это состояние. Итак, этот код:

setSearchedValue({ selectedVideo: singleRenderedVideo })

... установит состояние для объекта только со свойством selectedVideo. У него больше нет свойства видео.

У вас есть два варианта:

  1. выполнить неглубокое слияние
setSearchedValue(previous => ({
  ...previous,
  selectedVideo: singleRenderedVideo
}));
Имеют две отдельные переменные состояния. Для такого случая, как ваш, я рекомендую сделать это так.
const [ videos, setVideos ] = useState([]);
const [ selectedVideo, setSelectedVideo ] = useState(null);

// ...

setSelectedVideo(singleRenderedVideo);
0 голосов
/ 21 июня 2020

Для параметра searchValue установлено значение {selectedVideo: ...}. Другое свойство, потому что у нового значения этого свойства нет. Вы должны включить свое свойство видео, когда вы устанавливаете searchValue. Необходимо установить SearchValue ({... searchValue, selectedVideo: newValue})

...