【问题标题】:Render after API call ReactJSAPI 调用 ReactJS 后渲染
【发布时间】:2019-08-01 19:46:06
【问题描述】:

Alexnm 展示了您必须提供的非常恶心的架构,以便在服务器响应客户端之前让服务器等待 API 调用完成。

他表明,您必须首先将整个应用程序的每个组件记录在一个单一的、非分层的平面列表中,然后过滤每个组件,以查看一个组件是否具有 API“data- 每个请求的需求”,然后将该 API 请求的输出存储在 global redux 对象中(也很恶心),然后以某种方式传递它回到对象,希望它不会与其他请求发生冲突。

这是因为 ReactJS“lifecycle”钩子实际上根本不是生命周期钩子,而是 "fast and free" (and fun)

我并不真正关心这些库、ES[xyz] 语法和奇怪的哲学,但我想做的是返回一个 http 响应 after 并且 API 调用是制作,即

render() {
    // do an API call.
    // return a response.
}

我已经看到使用 if fetch(xyz).then(() => {}) 和许多其他彩色括号和函数,我不完全确定参数的输入位置或输出位置,我似乎无法弄清楚如何简单地 在上一行代码完成之前推迟下一行代码。在语法优美的then(() => {}) 中,我根本无法以任何方式返回值。它被称为 function,但我很难实现除副作用之外的任何东西,并且无法返回任何种类。

有谁知道如何让 render() 自己等待 API 调用?

【问题讨论】:

  • 这不是一个直接的答案(因此是评论),但是 - 你真的,真的不希望 render 阻止 API 调用!这会挂起页面,并且通常会使您的应用程序感觉迟缓。这个想法是你在你的fetch(在HTTP请求完成后运行)的then中调用你的组件上的setState,以便在数据到达后重新渲染你的组件。然后你可以同时渲染一个加载微调器/占位符/一些大的粗体文本说“IT'S LOADING I SWEAR”。
  • 文档的相关部分,如果您还没有偶然发现它:reactjs.org/docs/faq-ajax.html
  • 所以为了上下文,我正在做服务器端渲染(出于 SEO 原因)。我尝试在componentDidMount(和其他人)中进行API调用并在那里设置状态,但是从日志记录中,我发现rendercomponentDidMount完成之前被调用。 render 读取状态,但尚未设置状态。
  • 我不太清楚这里的问题是什么,它读起来基本上就像是在咆哮,首先是关于 React 的一些技术性(我不太熟悉,所以不能真正评论如果它们公平与否),然后是对 Promises 的咆哮,似乎只是因为它们是异步的?虽然我同情异步编程相当困难,但它是 1) 在 JS 中不可避免的,除非你想给用户一个真正可怕的体验,以及 2) 承诺,一旦你习惯了它们,让它比以往任何时候都容易。 (async/await,仍然是基于 promise 的,让它变得更容易)
  • @Display name: 啊,我明白了 - 在这种情况下,您可能不想在生命周期挂钩中获取数据(除非您希望请求在客户端上再次运行)。在渲染组件之前获取数据(例如,在您的服务器的请求处理程序中),并将其作为道具传递给您的组件。 Next.js 是一个很好的预烘焙包(不会被 Redux 等弄得一团糟)——希望它能给你一些启发。

标签: javascript reactjs asynchronous


【解决方案1】:

至于哲学——您可能想了解更多关于通量模式的内容——这是 Facebook 所采用的架构设计原则。努力是在单页应用程序或 SPA 中处理全局状态。

根据您当前的语法问题 - 您可以使用带有箭头函数的 Promise。 Promise 在 ES6 中被引入作为处理异步请求的解决方案。

使用您的示例fetch(xyz).then(() => {}) 可以通过以下方式同步执行请求:

render() {
   Promise.resolve(fetch(xyz))
   .then((response) => {
      // Do something with this response - for example..
      if (response.data) {
         axios.get("http://google.com")
         .then((response) => {

         console.log(response.data);

         })
         .catch((err) => {

         // Do something with this error
         console.log(err);
         })
      }
   })
})

return (
    <div>

    </div>
)
}

我不会涉及时间复杂性 - 但上述解决方案将触发 fetch(xyz) 请求,然后一旦该请求完成 - 我们将触发下一个请求。这称为承诺链 - 更多信息可以在这里找到:https://javascript.info/promise-chaining

如果您的目标是在组件渲染或安装后简单地进行调用并使用数据,您可以做一些更简洁和反应友好(非阻塞)的事情,如下例所示:

import React, {Component} from 'react';

class Example extends Component {
constructor(props) {
    super(props);

    this.state = {
      data: ''
    };
}

componentDidMount() {
   Promise.resolve(fetch(xyc))
   .then((response.data) => {
       this.setState({
         data:response.data
    });
   })
};

render() {
  const data = this.state

  return (
    {data} 
  )
}

【讨论】:

    猜你喜欢
    • 2018-04-20
    • 2020-06-30
    • 2022-01-25
    • 1970-01-01
    • 1970-01-01
    • 2017-05-20
    • 2017-06-11
    • 2019-02-20
    • 1970-01-01
    相关资源
    最近更新 更多