axios的另一个infinite useEffect()循环

时间:2020-05-27 07:20:07

标签: reactjs react-hooks

学习钩子,还有很多,我在使用useEffect()时陷入无限循环。在SO上尝试了此处给出的所有答案,但未能实现。

我想知道更多,因为我以前的应用程序正在运行。将把代码放到他们两个身上。也许有人可以帮助我解决我的问题。

如果这些应用看起来对某人来说很熟悉,那么是的,它们来自粗制滥造的课程,但是这里是使用setState和类制作的。


编辑:

从{p>中删除了对象{}

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

我已经在搜索答案时添加了它。


无限循环应用程序:

Code Sanbox Link

App.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
    }
});

还有我正在使用的应用程序:

App.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 个答案:

答案 0 :(得分:2)

代码看起来正确,但是我不确定为什么要从useEffect的{​​{1}}中传递空对象。 在这里:-

app.js

您的函数可能需要一个字符串。

答案 1 :(得分:1)

请像这样在SearchBar.js中更改代码

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

希望这对您有所帮助。

答案 2 :(得分:1)

您应该使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;

You can take a look at the updated sandbox.

答案 3 :(得分:1)

事实证明,要获得我想要的结果(仅在我在searchBar中写一些东西并按Enter / Return后才显示结果),我只需要删除useEffect()函数:

由Bobby B.(助教)

useEffect在每个渲染上都被调用,因此,当应用首次加载其 没有搜索字词就被调用(抛出400)。的 最简单的解决方案是提供默认搜索字词:

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

或者,如果您不希望将其从App.js中完全删除, 最初的默认图片搜索功能。

我从没想过,可以跳过useEffect()。我确定,它已在钩子中用作对componentDidMount()的某种替代。

谢谢大家的帮助!