将本地文件中的json数据加载到React JS中


78

我有一个React组件,我想从文件中加载JSON数据。即使我将变量数据创建为全局变量,控制台日志当前也不起作用

'use strict';

var React = require('react/addons');

// load in JSON data from file
var data;

var oReq = new XMLHttpRequest();
oReq.onload = reqListener;
oReq.open("get", "data.json", true);
oReq.send();

function reqListener(e) {
    data = JSON.parse(this.responseText);
}
console.log(data);

var List = React.createClass({
  getInitialState: function() {
    return {data: this.props.data};    
  },
  render: function() {
    var listItems = this.state.data.map(function(item) {
        var eachItem = item.works.work;        

        var photo = eachItem.map(function(url) {
            return (
                <td>{url.urls}</td> 
            )
        });
    });
    return <ul>{listItems}</ul>
  }
});

var redBubble = React.createClass({
    render: function() {
      return (
        <div>
          <List data={data}/>          
        </div>
      );
    }
  });

module.exports = redBubble;

理想情况下,我希望这样做,但它不起作用-它尝试在文件名的末尾添加“ .js”

var data = require('./data.json');

最好的方式,最好是“反应”方式的任何建议,将不胜感激!


1
console.log作品就好了,你只是在调用它之前reqListener是不断调用。
乔丹(Jordan)

感谢乔丹的回复。在代码中,它在reqListener之后,因此我不确定是否理解。您能详细说明一下吗?
德斯蒙德

1
您的Ajax请求需要时间。JavaScript在继续执行下一条指令之前不会等待请求完成(因为请求可能需要几分钟甚至几小时才能完成)。我们称此为“异步”(有时称为“非阻塞”)执行。在send()被调用之后,立即console.log被调用...,不久之后,Ajax请求完成并被reqListener调用。如果您希望仅在Ajax请求完成后才发生某事,则必须在中进行reqListener
乔丹


谢谢约旦,这确实有意义。感谢您抽出宝贵的时间来解释,其他链接也为您提供了帮助。我试图将我所有的React代码移到reqListener中,这样它就可以在回调中工作,但这似乎是个坏主意。有没有办法在运行其余代码之前等待响应?再次感谢。
德斯蒙德

Answers:


16

您正在打开一个异步连接,但是您已经编写了代码,就像它是同步的一样。该reqListener回调函数将不会与你的代码同步执行(即前React.createClass),但你的整个段已运行后,才和响应已经从远程位置接收。

除非您使用零延迟量子纠缠连接,否则在您运行所有语句之后就很好了。例如,要记录接收到的数据,您将:

function reqListener(e) {
    data = JSON.parse(this.responseText);
    console.log(data);
}

我没有data在React组件中看到使用,因此我只能从理论上提出建议:为什么不在回调中更新您的组件?


非常感谢约翰的帮助。我一直在研究如何在回调上更新组件,但运气不佳。与国家有关吗?我仍然是React的新手!我已经更新了代码以显示组件的工作方式-您能告诉我如何在回调中传递数据吗?再次感谢!
Desmond

@Desmond是的,状态可以正常工作,因为当状态更改时,组件将被重新呈现。
约翰·威兹

4
zero-latency quantum-entanglement connection😂也许是时候发明这些了,这样人们就不必再学习异步了……
ssc

142

我正在尝试做同样的事情,这对我有用(ES6 / ES2015):

import myData from './data.json';

我从一个回答本机的线程上问这个问题的答案得到了解决方案:https : //stackoverflow.com/a/37781882/176002


11
如果您将此方法与webpack一起使用,则需要json-loader用于导入的json文件。
kevr

3
谢谢!我一直在寻找一种在JSX中访问json数据的简单方法,这就是事实!
马特·布兰德

6
请注意,这会将您的JSON编译到分发包中,从而使热交换JSON文件成为不可能。对于许多用例来说,这可能很好,但不适用于我的情况。
威尔逊·比格斯

该答案应被标记为最准确的答案,但带有json-loader包装示例
Syed Aqeel

为我工作。我正在使用汇总。以前曾var data = import(‘./data.json’)导入过Promise。将其更改为可以import data from ‘./data.json’直接访问导入的对象。
Max MacLeod

25

使文件可用于组件的最简单,最有效的方法是:

var data = require('json!./data.json');

注意json!路径之前


3
除非您为此添加了一个库,否则这将无法工作。因为React默认不支持此功能。示例库:-npmjs.com/package/json-loader
Gopinath Langote '17

2
json-loader我相信,Webpack的新版本中包含此文件,但是您可能仍需要在Webpack配置中添加一些内容才能使用该确切语法。做一些研究。
agm1984

@ agm1984,自2015年以来情况发生了变化,如果您提供完整的答案,那就太好了。
塞萨尔D. Velandia

1
我相信最新的Webpack版本包括json-loader,因此您无需安装它或在配置文件中声明它。我建议您尝试import FILE_AS_VARIABLE from './file/location.json'
agm1984 '10 / 10/30


11
  1. 安装json-loader

    npm i json-loader --save

  2. datasrc以下位置创建文件夹:

    mkdir data

  3. 把你的文件放在那里

  4. 加载文件

    var data = require('json!../data/yourfile.json');


不使用时,A出现“关键依赖性:依赖性请求是一个表达式”错误json!。谢谢。
secavfr

1
无论如何,我可以从src文件夹外部使用.json文件吗?我正在为我的项目使用create-react-app
Chamod Pathirana

8

如果您有几个json文件:

import data from 'sample.json';

如果要动态加载许多json文件之一,则可能必须fetch改用:

fetch(`${fileName}.json`)
  .then(response => response.json())
  .then(data => console.log(data))

1

我的JSON文件名:terrifcalculatordata.json

[
    {
      "id": 1,
      "name": "Vigo",
      "picture": "./static/images/vigo.png",
      "charges": "PKR 100 per excess km"
    },
    {
      "id": 2,
      "name": "Mercedes",
      "picture": "./static/images/Marcedes.jpg",
      "charges": "PKR 200 per excess km"
    },
    {
        "id": 3,
        "name": "Lexus",
        "picture": "./static/images/Lexus.jpg",
        "charges": "PKR 150 per excess km"
      }
]

首先,首先导入:

import calculatorData from "../static/data/terrifcalculatordata.json";

然后返回后:

  <div>
  {
    calculatorData.map((calculatedata, index) => {
        return (
            <div key={index}>
                <img
                    src={calculatedata.picture}
                    class="d-block"
                    height="170"
                />
                <p>
                    {calculatedata.charges}
                </p>
            </div>
                  


0

如果您要加载文件(作为应用功能的一部分),那么最好的方法是包含并引用该文件。

另一种方法是要求文件,并在运行时加载它。这可以通过FileAPI完成。还有一个有关使用它的StackOverflow答案: 如何使用Javascript打开本地磁盘文件?

我将包括一个稍作修改的版本,以便在React中使用它:

class App extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      data: null
    };
    this.handleFileSelect = this.handleFileSelect.bind(this);
  }

  displayData(content) {
    this.setState({data: content});
  }

  handleFileSelect(evt) {
    let files = evt.target.files;
    if (!files.length) {
      alert('No file select');
      return;
    }
    let file = files[0];
    let that = this;
    let reader = new FileReader();
    reader.onload = function(e) {
      that.displayData(e.target.result);
    };
    reader.readAsText(file);
  }

  render() {
    const data = this.state.data;
    return (
      <div>
        <input type="file" onChange={this.handleFileSelect}/>
        { data && <p> {data} </p> }
      </div>
    );
  }
}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.