从 React.js 进行 RESTful API 调用

2024-01-27

我正在为同构 JavaScript 应用程序做一个 POC,以从服务器端渲染 HTML。 POC 使用简单的 HTML,但我想进行 API 调用并获取 JSON 响应并将其发送到渲染函数。我尝试了各种方法但它不起作用。

我缺少什么?我对 React.js 很陌生。

loadCategoriesFromServer: function() {
        var self = this;

// get walking directions from central park to the empire state building
    var http = require("http");
    url = "api url here";
        var request = http.get(url, function (response) {
            // data is streamed in chunks from the server
            // so we have to handle the "data" event    
            var buffer = "", 
                data,
                route;

            response.on("data", function (chunk) {
                buffer += chunk;
            }); 

            response.on("end", function (err) {
                
              data = JSON.parse(buffer);
                
              //console.log(data.d);
              //console.log(data.d.Items);
                self.setState({
                    categories: data.d.Items
                });
            }); 
        });
    }, // load from server end

    getInitialState: function() {
        return { categories: [] };
    },

    componentWillMount: function() {
        console.log("calling load categories")
        this.loadCategoriesFromServer();
    },
render: function () {
        
        //console.log("data");
        //console.log(this.state.categories);
      
        var postNodes = this.state.categories.map(function (cat) {
          console.log(cat);
        });
    
        return (
          <div id="table-area">
             //i want to paint the data here..
          </div>
        )
      }

  });

使用获取组件内部componentWillMount不是一个正确的地方,以防您需要渲染服务器端。您需要以某种方式将其从组件中移出,并在获取实际数据后将其作为道具传递 - 例如,正如 @JakeSendar 在他的回答中所建议的那样。

我有一些使用 React 制作同构应用程序的经验,我面临的主要问题是如何等到所有数据加载完毕后再进行首次渲染

正如@FakeRainBrigand 在评论中已经提到的,不仅有一种方法可以做到这一点,而且这取决于您的要求。

构建同构应用程序的方法很少,从我的角度来看,一些有趣的是:https://github.com/webpack/react-starter https://github.com/webpack/react-starter and http://fluxible.io/ http://fluxible.io/

但是,正如我自己发现的,最优雅的方法是为 React 组件组织异步渲染,特别是使用 RxJS。

一般来说,我的申请结构如下:

  1. 视图 - 没有任何逻辑的 React 组件(只是一个视图)
  2. models - 具有当前状态的可观察量(使用超级代理加载初始数据,然后与其他模型和/或操作结果相结合)。 在简单的情况下,它是这样的:

    Rx.Observable.defer(fetchData).concat(updatesSubject).shareReplay()

  3. 操作(或意图) - 用于收集用户输入、执行某些操作并将操作结果分派给订阅者模型和/或其他操作的观察者。在简单的情况下,例如:

    updatesSubject = new Rx.Subject();

    action = new Rx.Subject(); action.switchMap(asyncRequest).subscribe(updatesSubject)

  4. 组件 - 由模型、其他组件和操作组合而成的 Observables(虚拟 DOM 元素流)(我对此有一个注释,解释了如何以及为何使用 RxJS 创建 Observable React 元素 https://gist.github.com/zxbodya/20c63681d45a049df3fc),现在我还计划添加部分组件(元组来自:react 组件、可观察对象、观察者和属性。部分使用 DI 填充)

  5. 路由器 - 负责处理位置更改的组件, 一般来说,主要功能是将位置更改映射到虚拟 DOM 元素和元信息流。但在细节上,在我的情况下有点复杂(url生成、活动url突出显示、导航时处理滚动,也有可能嵌套路由和多个视图)

所有这些都是使用 DI 容器组装在一起的,在我的例子中类似于angular2 DI 容器 https://github.com/angular/di.js,但针对我的特定需求进行了很多简化。

组件、模型和操作是使用 DI 创建的。

在服务器端应用程序是这样的:

var rootInjector = new Injector();
// setup server specific providers
rootInjector.provide(..., ...)

app.get('/*', function(req,res){
    var injector = rootInjector.createChild();
    // setup request specific providers
    injector.provide(..., ...);

    injector.get(Router)
       .first()
       .subscribe(function(routingResult){ 
          res.render('app', {
              title: routingResult.title,
              content: React.renderToString(routingResult.content)
          });
       });
}

和客户端类似:

var rootInjector = new Injector();
// setup server specific providers
// actually this is omitted in my case because default providers are client side
rootInjector.provide(..., ...)
contentElement = document.getElementById('#content');

rootInjector.get(Router)
   .subscribe(function(routingResult){ 
      document.title = routingResult.title;
      React.render(routingResult.content, contentElement)
   });

与 Flux 相比,它是一种更具声明性且更强大的组织应用程序的方式。对于同构应用程序 - 对我来说,它看起来比各种使用 Flux 的黑客要好得多。但当然也有缺点...... - 它更复杂。

可能稍后,我将开源所有这些,但现在 - 它还没有准备好发布。

UPD1:

原始答案有点过时(稍后我计划更新它),并且我在这方面取得了一些进展。

上面提到的代码链接,已经开源:

  • DI容器:di1 https://github.com/zxbodya/di1
  • React 组件的容器(将视图连接到可观察对象和观察者):rx-反应容器 https://github.com/zxbodya/rx-react-container
  • 入门模板,用于使用 RxJS 和 React 以及上面的库实现同构小部件:反应式小部件 https://github.com/zxbodya/reactive-widgets

关于完整的应用程序(工作仍在进行中,文档不太好,但总的来说应该很清楚):

  • 专为同构反应式应用程序构建的路由器router1 https://github.com/zxbodya/router1并对组件进行反应以使用它router1-反应 https://github.com/zxbodya/router1-react
  • 带有路由器和上述所有库的应用程序模板:router1-应用程序模板 https://github.com/zxbodya/router1-app-template
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

从 React.js 进行 RESTful API 调用 的相关文章

随机推荐