从useEffect中的api获取并相应地渲染组件

时间:2020-06-10 22:23:51

标签: javascript reactjs axios react-hooks

我在基于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数据返回然后相应地渲染组件?

3 个答案:

答案 0 :(得分:1)

在您的用户中,尝试使用过滤器:

setPoll(poll.filter(poll => poll.id !== id));

请确保使用您的标识符替换ID

答案 1 :(得分:1)

标准方法是为加载和错误状态设置其他变量

const Poll = (props) => {

    const [poll, setPoll] = useState(null);
    const [loading, setLoading] = useState(false);
    const [error, setError] = useState(false);


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


    if(error) return <span>error<span/>
    if(loading) return <span>loading<span/>
    return (
        <div>
           // your poll data

        </div>
    )
}

答案 2 :(得分:1)

您无需跟踪const [found, setFound] = useState(1)之类的API调用状态。只需检查民意调查是否存在,您还可以创建一个新的状态变量来跟踪错误。

例如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