еще один бесконечный useEffect () l oop с аксиомами - PullRequest
1 голос
/ 27 мая 2020

обучающих ловушек, и я застрял в бесконечном oop при использовании useEffect (). Я попробовал все ответы, приведенные здесь, на SO, но не смог их реализовать.

Мне интересно больше, потому что мое предыдущее приложение работает. Поместим код им обоим. Может быть, кто-то может помочь мне с моей проблемой.

Если эти приложения кажутся кому-то знакомыми, то да, они взяты из курса udemy, но здесь они сделаны с использованием setState и классов.


EDIT:

удалил объект {} из

  useEffect(() => {
    onTermSubmit({});
  }, [])

Я добавил его во время поиска ответа.


Infinite l oop Приложение:

Код Sanbox Link

Приложение js

import React, { useState, useEffect } from 'react';
import SearchBar from "./SearchBar";
import youtube from "../apis/youtube";
import VideoList from "./VideoList";

const App = () => {
  const [videos, setVideos] = useState([]);

  const onTermSubmit = async (textInput) => {
    const response = await youtube.get("/search", {
      params: { q: textInput }
    });
    setVideos(response.data.items);
  }

  useEffect(() => {
    onTermSubmit();
  }, [])

  return (
    <div className="ui container">
      <SearchBar onFromAppSubmit={onTermSubmit} />
      <VideoList foundVideos={ videos } />
    </div>
  );
}

export default App;

SearchBar. js

import React, { useState } from "react";

const SearchBar = ({onFromAppSubmit}) => {
    const [textInput, setTextInput] = useState("");

    const onTextInputChange = event => {
        setTextInput(event.target.value);
    }

    const onFormSubmit = event => {
        event.preventDefault();

        onFromAppSubmit(textInput);
    }

    return(
    <div className="search-bar ui segment">
        <form onSubmit={onFormSubmit} className="ui form">
            <div className="field">
                <label>Video Search</label>
                <input
                    type="text"
                    placeholder="Type in to search for videos"
                    value={textInput}
                    onChange={onTextInputChange}
                    />
            </div>
        </form>
    </div>
    );
}

export default SearchBar;

VideoList. js

import React from "react";
import VideoItem from "./VideoItem";

const VideoList = ({foundVideos}) => {
    const renderedList = foundVideos.map((video) => {
        return(
            <VideoItem />
        );
    })

    return(
        <div>
            {renderedList}
        </div>
    );
}

export default VideoList;

VideoItem. js

import React from "react";

const VideoItem = () => {
    return(
        <div>
            VideoItem
        </div>
    );
}

export default VideoItem;

youtube. js

import axios from "axios";

const KEY = "myVerySecretKey^^";

export default axios.create({
    baseURL: "https://www.googleapis.com/youtube/v3",
    params: {
        part: "snippet",
        type: "video",
        maxResults: 5,
        key: KEY
    }
});

И мое рабочее приложение :

Приложение js

import React, { useState, useEffect } from 'react';
import unsplash from "../api/Unsplash";
import SearchBar from "./SearchBar";
import ImageList from "./ImageList";


const App = () => {
  const [images, setImages] = useState([]);

  const onSearchSubmit = async (inputText) => {
    const response = await unsplash.get("/search/photos", {
      params: { query: inputText},
    });
    setImages(response.data.results);
  }

  useEffect(() => {
        onSearchSubmit();
  }, [])

  return (
    <div className="ui container" style={{marinTop: "10px"}}>

      <SearchBar whenSubmitted={onSearchSubmit} />
      <ImageList foundImages={images}/>
    </div>
  );
}

export default App;

SearchBar. js

import React, { useState } from "react";

function SearchBar({whenSubmitted}){
    const [inputText, setInputText] = useState("");

    function onInputChange(event){
        const writtenText = event.target.value;
        setInputText(writtenText);
    }

    function onFormSubmit(event){
        event.preventDefault();         //to prevent the form to refresh the whole form

        whenSubmitted(inputText);
    }

    return (
        <div className="ui segment">
            <form onSubmit={onFormSubmit} className="ui form">
                <div className="field">
                    <label>Image Search</label>
                    <input
                        type="text"
                        value={inputText}
                        onChange={onInputChange}
                        placeholder="Search"
                    />
                </div>
            </form>
        </div>
    );
}

export default SearchBar;

Ответы [ 4 ]

1 голос
/ 27 мая 2020

Код выглядит правильно, но я не уверен, почему вы передали пустой объект из useEffect вашего app.js. Здесь: -

useEffect(() => {
    onTermSubmit({});
  }, [])

Ваши функции могут ожидать строку.

1 голос
/ 27 мая 2020

Вы должны сделать свой useEffect зависимым от вашего searchValue, чтобы поиск запускался каждый раз при отправке нового searchValue:

import React, { useState, useEffect } from "react";
import SearchBar from "./SearchBar";
// import youtube from "../apis/youtube";
import VideoList from "./VideoList";

const App = () => {
  const [videos, setVideos] = useState([]);
  const [searchValue, setSearchValue] = useState("");


  useEffect(() => {
    (async () => {
      // const response = await youtube.get("/search", {
      //   params: { q: textInput }
      // });
      setVideos([searchValue, "some", "random", "items"]); //mocked the axios connection
    })();
  }, [searchValue]);

  return (
    <div className="ui container">
      <SearchBar
        onFromAppSubmit={newSearchValue => setSearchValue(newSearchValue)}
      />
      <VideoList foundVideos={videos} />
    </div>
  );
};

export default App;

Вы можете взглянуть на обновленная песочница.

0 голосов
/ 28 мая 2020

Что ж, оказывается, что для получения желаемого результата (показывать результаты только после того, как я напишу что-нибудь в searchBar и нажму Enter / Return), мне просто нужно стереть функцию useEffect ():

Бобби Б. (Ассистент преподавателя)

useEffect вызывается при каждом рендеринге, поэтому, когда приложение впервые загружает его, он вызывается без поискового запроса (который выдает 400). Самым простым решением было бы предоставить условие поиска по умолчанию:

useEffect(() => {
    onSearchSubmit('cats');
  }, []);

Или вы можете удалить его из приложения. js полностью, если вы не искали эту первоначальную функцию поиска изображений по умолчанию.

Никогда бы не подумал, что можно пропустить useEffect (). Я был уверен, что он используется в хуках как своего рода замена для componentDidMount ().

Спасибо всем за помощь!

0 голосов
/ 27 мая 2020

Пожалуйста, измените свой код в SearchBar. js вот так

onChange={(evt) => onInputChange(evt)}

Надеюсь, это вам поможет.

...