【问题标题】:ReactJS: Axios' async request is returning 'undefined'ReactJS:Axios 的异步请求返回“未定义”
【发布时间】:2020-06-14 01:55:29
【问题描述】:

我正在做一个使用电影 DB API 是 ReactJs 的小项目,我在使用异步函数时遇到问题,我在项目的许多部分中进行 api 调用并在所有项目中都有效,但现在不是工作。

我的 axios 配置:

export default axios.create({
  baseURL: 'https://api.themoviedb.org/3/',
  params: {
    api_key: process.env.REACT_APP_API,
  },
});

我的容器里有这个

const { setMenuSelected } = useContext(MovieContext);
const [movie, setMovie] = useState({})
const [recommendations, setRecommendations] = useState([]);
const [isLoading, setIsLoading] = useState(true)

useEffect(() => {
  animateScroll.scrollToTop({ smooth: true });
  setMenuSelected('');
  getMovieRecommendations(setRecommendations, match.params.id, setIsLoading);
  setMovie(getMovieDetails(match.params.id, setMovie));
}, [match.params.id, recommendations, isLoading]);

我正在获取其他文件中的数据只是为了组织项目

export const getMovieRecommendations = async (
  setRecommendations,
  movieId,
  setIsLoading) => {
  const res = await api.get(`/movie/${movieId}/recommendations`);
  setRecommendations(res.results);
  setIsLoading(false);
}

为了渲染电影列表,我将推荐传递给仅使用地图渲染每部电影的组件,

<MovieList header={'Recommentadion'} movieList={recommendations} />

但应用程序总是崩溃说“无法读取未定义的属性'map'”,我查看了 chrome 中的网络属性,我的请求完成且没有错误。

更新:

console.log(JSON.stringify(res)) 的返回我删除了结果,所以它不会变得太大

{
  "data":{
    "page":1,
    "results":[
      {},
      {},
      {},
      {},
      {},
      {},
      {},
      {},
      {},
      {},
      {},
      {},
      {},
      {},
      {},
      {},
      {},
      {},
      {},
      {}
    ],
    "total_pages":2,
    "total_results":40
  },
  "status":200,
  "statusText":"",
  "headers":{
    "cache-control":"public, max-age=14400",
    "content-type":"application/json;charset=utf-8",
    "etag":"W/\"56ca661f28e43dc3dd2ce41816b517c5\""
  },
  "config":{
    "transformRequest":{

    },
    "transformResponse":{

    },
    "timeout":0,
    "xsrfCookieName":"XSRF-TOKEN",
    "xsrfHeaderName":"X-XSRF-TOKEN",
    "maxContentLength":-1,
    "headers":{
      "Accept":"application/json, text/plain, */*"
    },
    "method":"get",
    "baseURL":"https://api.themoviedb.org/3/",
    "params":{
      "api_key":"fe5b485ed12153ca357c3275cfad6c5c"
    },
    "url":"https://api.themoviedb.org/3/movie/399121/recommendations"
  },
  "request":{

  }
}

【问题讨论】:

  • 能否也向我们展示您的 MovieList 组件?
  • 这个其实和axios有关。您必须获取 res.data.results 而不是 res.results。调试并查看您是否真的获得了该属性。并尝试检查 res.data 而不是 res.results。
  • 你错过了这个await api.get吗?我猜你的意思是await axios.get(..)
  • @DhavalChheda 这确实有效,谢谢。

标签: javascript reactjs api async-await axios


【解决方案1】:

尝试做:

const res = await api.get(`/movie/${movieId}/recommendations`);
console.log(JSON.stringify(res));

这会将整个 JSON 对象打印到控制台中的字符串中。由于您未定义且没有错误,因此您很可能错误地访问了 JSON 对象。通过打印出内容,这将向您展示您的 JSON 对象的外观,以便您可以成功访问“结果”属性。

【讨论】:

  • 你能用返回的 JSON 更新问题吗?我怀疑您只是错误地访问了“.results”属性。
【解决方案2】:

解释 axios.create 和示例

axios.create 用于初始..(配置)

const axios = Axios.create({ withCredentials: false/true });

现在,像这样使用 axios 创建一个函数:

function get(...args) {
  return axios.get(...args)
}

一边写一边打电话:

const res = await get(`/movie/${movieId}/recommendations`);

【讨论】:

    【解决方案3】:

    我认为这对你有帮助。 你应该像这样导出你的 axios 配置:

    const APIClient = axios.create({
      baseURL: 'https://api.themoviedb.org/3/',
      params: {
        api_key: process.env.REACT_APP_API,
      }
    });
    
    export default APIClient;
    

    然后将其导入以获取另一个文件中的数据:

    import  APIClient  from "YOUR AXIOS CONFIG FILE";
    
      export const getMovieRecommendations = async (movieId) => {
      const { data } = await APIClient.get(`/movie/${movieId}/recommendations`);
      return data;
    }
    

    在你的容器中设置这个:

    const { setMenuSelected } = useContext(MovieContext);
    const [movie, setMovie] = useState({})
    const [recommendations, setRecommendations] = useState([]);
    const [isLoading, setIsLoading] = useState(true)
    
    const getList=async(movieId)=>{
    const res = await getMovieRecommendations(movieId);
      setRecommendations(res.results);
      setIsLoading(false);
    }
    
    useEffect(() => {
      animateScroll.scrollToTop({ smooth: true });
      setMenuSelected('');
      getList(match.params.id);
      setMovie(getMovieDetails(match.params.id, setMovie));
    }, [match.params.id, recommendations, isLoading]);
    

    【讨论】:

    • 我认为我会这样做,这样我就不需要将函数传递给其他人了。
    • 您确定“结果”在您从 api 返回的数据中吗?
    • 考虑 axios 总是返回一个“数据”参数。
    猜你喜欢
    • 2018-03-22
    • 2019-08-24
    • 2019-06-18
    • 2018-04-30
    • 2020-09-05
    • 2018-08-09
    • 2022-01-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多