【问题标题】:How to render something that is async in React?如何在 React 中渲染异步的东西?
【发布时间】:2021-08-29 03:32:04
【问题描述】:

我正在制作一个反应应用程序,该应用程序与一个向我的应用程序提供数据的 API 配合使用。在我的数据库中,我有关于地图上大头针的数据。我想在我的反应应用程序上显示这些引脚的信息,我希望它们呈现。我通过 axios 和这个 url 获得了这些信息:http://warm-hamlet-63390.herokuapp.com/pin/list 我想使用 axios.get(url) 从该 url 检索信息,对 JSON 数据进行字符串化,然后将其解析为引脚数组。

问题: 我的页面将在我从服务器取回数据之前呈现,因为 axios 是异步的,所以我将无法显示任何内容。 UseEffect 和 useState 不起作用,因为我首先需要一些东西(我认为)。

我尝试过的: 我尝试使用 useEffect 和 useState,但正如我所说,我认为我首先需要一些东西来改变它。我也尝试使用await,但是await不会停止整个React App,直到它有响应,尽管如果有什么东西可以停止应用程序并等到我有包含信息的数组以便我可以显示然后在应用程序上。我用异步尝试了一切。我对 React 还很陌生,所以我可能有一些基本的东西(?)。我已经做了好几天了,我无法以任何方式让它工作。任何帮助、youtube 视频、文档、示例都是帮助。任何事物。我到底要如何渲染需要等待服务器响应的东西?

我的代码:

//function that stores the data in the result array, 
//but result array will only be available after the 
//server response, and after the page is rendered
async function pin(){

  const result = []
  var url = "http://warm-hamlet-63390.herokuapp.com/pin/list"

  const res = await axios.get(url)
  
  console.log(res.data.data);

  if(res.data){
    const txt = JSON.stringify(res.data.data)
    const result = JSON.parse(txt)
    console.log(result);
  }
  return result;
}
class App extends React.Component{

  render(){
    return(
      <div>
        <Pin/>
        <Mapa/>
      </div>
    )
  }
}


export default App

【问题讨论】:

  • 你是在渲染组件还是数据?
  • 任何解决方案都可以,因为我想在组件上使用上述数据,这有意义吗?
  • 你不能把结果写到this.someVar = result;然后用 if(someVar)? 在模板中检查它?
  • 那么,哪个答案对您有帮助?对于花时间帮助您和潜在未来观众的人,您应该将其标记为正确。这是使这个网站很棒的部分原因。

标签: javascript reactjs async-await axios


【解决方案1】:

请放心,useEffect() 会起作用的。当内容从服务器返回时,您需要使用条件来有条件地呈现内容。

在下面的示例中,如果结果的长度 Loading ... 将呈现在包含的 &lt;div&gt; 中,一旦收到结果,状态将被更新(触发重新呈现)并且将再次评估模板中的条件。这一次虽然results 将有一个length &gt; 1,所以results 将被渲染而不是Loading ...

我假设你的函数 pin() 正在返回结果数组。

const app = (props) => {
    
  const [results, setResult] = useState([]);
    
  React.useEffect(() => {
    const getPin = async () => {
      if (!results) {
        const results = await pin();
        setResult([…results])
      }
    }
    getPin();
  },[results]);
    
  return (
    <div>
      {result.length ? result : 'Loading ... '}
    </div>
  )
}

【讨论】:

    【解决方案2】:

    我不完全理解您要输出的内容,但您通常如何使用 useState 钩子和 useEffect 钩子来处理此问题,请参见下面的示例。

      //function that stores the data in the result array, 
      //but result array will only be available after the 
      //server response, and after the page is rendered
      const pin = () => {
      const [result, setResults] = useState([]);
      var url = "http://warm-hamlet-63390.herokuapp.com/pin/list"
    
      useEffect(() => {
        //Attempt to retreive data
        try {
          const res = transformData();
    
          if (res) {
            // Add any data transformation
            setResults(transformData(res))
          }
          else {
            throw (error)
          }
        }
        catch (error) {
          //Handle error
        }
      }, [])
    
      // Handle data transformation
      const transformData = async () => {
        const res = await axios.get(url)
    
        const txt = JSON.stringify(res.data.data)
        const result = JSON.parse(txt)
    
        return result
      }
    
      if (!result) {
        // Return something until the data is loaded (usually a loader)
        return null
      }
    
      // Return whatever you would like to return after response succeeded
      return <></>;
    }
    

    这一切都假设 Pin 是您在代码中显示的组件,或者,可以将调用移至父组件,您可以添加如下所示的内联检查以呈现 pin 并将一些数据传递给它。

    {result && <Pin property={someData} />}
    

    只是一点背景,useEffect 钩子在“[]”末尾显示了一个空的依赖数组,这意味着它只会运行一次,然后一旦数据更新了状态,这将导致重新渲染,更改应该是在您的组件中可见

    【讨论】:

    • 感谢您帮助我。我收到此错误:Unexpected reserved word 'await' 可能是因为您发布的代码中没有“异步”,但我也不知道该放在哪里
    • 不能使用await而不将包含函数声明为async
    • 是的,抱歉,我忘记了我已经更新了上面的代码,并将 axios 移到了函数中,因为 React 不喜欢你在 useEffect 钩子中使用异步。
    • 否则你可以像这样添加异步useEffect(async () =&gt; {}
    • @VukVucic 实际上不起作用。但是有办法解决它,请参阅stackoverflow.com/a/56838577/9830755 或我的回答。
    猜你喜欢
    • 1970-01-01
    • 2021-07-27
    • 1970-01-01
    • 2019-03-21
    • 2017-10-06
    • 2017-10-08
    • 2018-05-15
    • 1970-01-01
    • 2022-11-15
    相关资源
    最近更新 更多