【问题标题】:React Component JSON Callback ScopeReact 组件 JSON 回调范围
【发布时间】:2016-05-03 16:28:58
【问题描述】:

我正在使用 generator-react-webpack 创建一个 React Web 应用程序。此 Web 应用程序依赖于 JSON 提要 - 其中一个托管在不支持 JSONP 的 CDN 上,并且 CDN url 是 Web 应用程序的子域。有没有办法从 React 组件中返回 JSON 数据?

基本反应组件:

var AppComponent = React.createClass({
    loadData: function() {
        jQuery.getJSON(jsonFile.json?callback=?)
        .done(function(data) {
            console.log(data);
        }.bind(this));
    },
    render: function(){
        return ( ... );
    }
});

我尝试了一些解决方案,得出的结论是我需要在 JSON 文件上定义自己的回调,如下所示:

JSON:

handleData({
    "data": "hello World"
})

有没有办法在反应组件中定义handleData 回调,或者从反应组件访问的响应?任何关于我如何让它发挥作用的想法都非常感谢。谢谢!

【问题讨论】:

    标签: javascript json reactjs webpack


    【解决方案1】:

    这看起来像是一种奇怪的做事方式,尤其是在您使用 jQuery 的部分。这是一个客户端实用程序,可以克服不知道所有内容在哪里并且无法直接访问您的元素的问题。当你使用 React 和 Webpack 进行捆绑时使用它是没有意义的:React 已经知道所有东西在哪里(使用 refs),而 Webpack 意味着你可以使用常规的通用 Node 模块来完成你需要做的所有事情。

    我建议使用类似 request 或类似的通用提取 API:

    // loadData.js
    var request = require('request');
    var loadData = function(urlYouNeed, handler) {
      request(urlYouNeed, function(error, response, body) {
        if (error) {
          return handler(error, false);
        }
    
        // do anything processing you need on the body,
        var data = process(body);
        handler(false, data);
    };
    

    所以:只是一个你可以在你用require('./loadData') 定义的任何组件中需要的模块。然后在您的实际组件中执行以下操作:

    var loadData = require('./loadData');
    var AppComponent = React.createClass({
      getDefaultProps: function() {
        return {
          jsonURL: "cdn://whateverjson.json"
        };
      },
      getInitialState: function() {
        loadData(this.props.jsonURL, this.updateData);
        return {
          data: []
        }
      },
      updateData: function(err, data) {
        if (err) {
          return console.error(err);
        }
        data = secondaryEnsureRightFormat(data);
        this.setState({ data: data });
      },
      render: function(){
        var actualThings = this.state.data.map((entry, pos) => {
          return <Whatever content={entry} key={entry.dontUseThePosVariableUpThere}/>
        });
        return (
          <div>
            ...
            {actualThings}
            ...
          </div>
        );
      }
    });
    

    干净得多。

    【讨论】:

    • 这很棒!我还是 nodejs 空间的新手,对请求一无所知。不过,似乎已经为我的 webpack javascript 文件添加了大量资源:-/ 你知道我是否也可以在开发环境中使用它吗? XMLHttpRequest cannot load. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:8000' is therefore not allowed access.
    • 如果你使用 Node,npmjs.com 几乎是所有好事发生的地方。您看到的错误意味着当涉及到使用其文件的其他站点时,您调用的 URL 已经设置了额外的安全性。您可能需要查看 CDN 的文档以了解如何访问该文件以进行 localhost 测试。此外,如果您的包太大,您可以随时尝试其他更简单的获取库(“superagent”是另一种流行的库),或者您甚至可以编写自己的,但通常不值得。
    【解决方案2】:

    如果我正确理解了这个问题,您只需以这种方式更改您的 loadData :

    loadData: function() {
        var c = this
        jQuery.getJSON(jsonFile.json?callback=?)
        .done(function(data) {
            c.handleData(data)
        });
    },
    
    handleData: function(data) {
        /* Implement here the function to handle the data */
    },
    

    【讨论】:

    • 我仍然收到错误:Uncaught ReferenceError: handleData is not defined
    • 你真的定义了handleData并通过c而不是this来调用它吗?这是一个非常常见的 React 方案,我每天都使用它,没有任何麻烦:)。顺便说一句,bind(this) 没用,所以我将其删除。
    • 是的,我仍然看到回调未定义:-(
    • 您究竟是如何调用 loadData 函数的?正确的方法是在 componentDidMount 中调用它。您能否更新您的代码以显示您打算如何调用它?
    猜你喜欢
    • 2014-02-14
    • 1970-01-01
    • 2011-03-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-01-11
    • 1970-01-01
    相关资源
    最近更新 更多