首页 > 解决方案 > 从 useEffect 中的 api 获取并相应地渲染组件

问题描述

我在 React 中基于 api 调用渲染组件时遇到了麻烦。我在 useEffect 挂钩中获取我的数据,用数据更新状态。在 api 获取所有数据之前状态为 null 一段时间,但到那时,组件正在使用 null 值呈现。这就是我所拥有的:

import React, { useEffect, useState } from 'react'
import axios from 'axios';
import { Redirect } from 'react-router-dom';

const Poll = (props) => {

const [poll, setPoll] = useState(null);
//if found is 0 not loaded, 1 is found, 2 is not found err
const [found, setFound] = useState(0);


useEffect(() => {
    axios.get(`api/poll/${props.match.params.id}`)
        .then(res => {
            console.log(res.data);
            setPoll(res.data);
            setFound(1);
        })
        .catch(err => {
            console.log(err.message);
            setFound(2);
        });
}, [])


if(found===2) {
    return(
        <Redirect to="/" push />
    )
}else{
    console.log(poll)
    return (
        <div>


        </div>
    )
}

}

export default Poll

这是我的解决方法,但感觉不应该这样做。如何设置它以便等待我的 api 数据返回然后相应地渲染组件?

标签: javascriptreactjsaxiosreact-hooks

解决方案


您不需要跟踪 API 调用的状态,例如const [found, setFound] = useState(1). 只需检查 poll 是否存在,您还可以创建一个新的状态变量来跟踪错误。

例如if (!poll) { return <div>Loading...</div>},当没有数据时,这将呈现一个带有“正在加载...”的 div。请参阅下面的代码,以获得完整的解决方案,

import React, { useEffect, useState } from 'react'
import axios from 'axios';
import { Redirect } from 'react-router-dom';

const Poll = (props) => {

   const [poll, setPoll] = useState(null);

   const [hasError, setHasError] = useState(false);


   useEffect(() => {
     axios.get(`api/poll/${props.match.params.id}`)
        .then(res => {
            console.log(res.data);
            setPoll(res.data);
        })
        .catch(err => {
            console.log(err.message);
            setHasError(true)
        });
  }, [])


  if(!poll) {
    console.log('data is still loading')
    return(
       <div>Loading....</div>
    )
   }

  if (hasError) {
   console.log('error when fetching data');

   return (
     <Redirect to="/" push />
   )
 }


 return (
   <div>
    {
      poll && <div>/* The JSX you want to display for the poll*/</div>
    }
   </div>
 );
}

export default Poll

推荐阅读