Laden von JSON-Daten aus der lokalen Datei in React JS


78

Ich habe eine React-Komponente und möchte meine JSON-Daten aus einer Datei laden. Das Konsolenprotokoll funktioniert derzeit nicht, obwohl ich die Variable erstelle Daten als globale Daten

'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;

Im Idealfall würde ich es lieber so machen, aber es funktioniert nicht - es versucht hinzuzufügen ".js" am Ende des Dateinamens .

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

Jeder Rat auf dem besten Weg, vorzugsweise dem "Reagieren" Weg, wäre sehr dankbar!


1
Das console.logfunktioniert einwandfrei, Sie rufen es einfach an, bevor reqListeneres jemals aufgerufen wird.
Jordan läuft

Danke für die Antwort Jordan. Im Code kommt es nach reqListener, daher bin ich mir nicht sicher, ob ich es verstehe. Könnten Sie bitte näher darauf eingehen?
Desmond

1
Ihre Ajax-Anfrage braucht Zeit. JavaScript wartet nicht auf den Abschluss der Anforderung, bevor mit der nächsten Anweisung fortgefahren wird (da die Ausführung der Anforderung Minuten oder sogar Stunden dauern kann). Wir nennen dies "asynchrone" (oder manchmal "nicht blockierende") Ausführung. Unmittelbar nach dem send()Aufruf console.logwird aufgerufen ... und einige Zeit später wird die Ajax-Anforderung beendet und reqListeneraufgerufen. Wenn Sie möchten, dass etwas erst nach Abschluss der Ajax-Anforderung passiert, müssen Sie dies veranlassen reqListener.
Jordan läuft


Danke Jordan, das macht jetzt Sinn. Vielen Dank, dass Sie sich die Zeit genommen haben, dies zu erklären, und der andere Link hat geholfen. Ich habe versucht, meinen gesamten React-Code in den reqListener zu verschieben, damit er im Rückruf funktioniert, aber das scheint eine schlechte Idee zu sein. Gibt es eine Möglichkeit, auf die Antwort zu warten, bevor der Rest des Codes ausgeführt wird? Danke noch einmal.
Desmond

Antworten:


16

Sie öffnen eine asynchrone Verbindung , haben Ihren Code jedoch so geschrieben, als wäre er synchron. Die reqListenerRückruffunktion wird nicht synchron mit Ihrem Code ausgeführt (d. H. Vorher)React.createClass ) ausgeführt, sondern erst, nachdem Ihr gesamtes Snippet ausgeführt wurde und die Antwort von Ihrem Remote-Standort empfangen wurde.

Sofern Sie sich nicht in einer Quantenverschränkungsverbindung ohne Latenz befinden, ist dies gut, nachdem alle Ihre Anweisungen ausgeführt wurden. Um beispielsweise die empfangenen Daten zu protokollieren, würden Sie:

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

Ich sehe die Verwendung datain der React-Komponente nicht, daher kann ich dies nur theoretisch vorschlagen: Warum aktualisieren Sie Ihre Komponente nicht im Rückruf?


Vielen Dank für Ihre Hilfe, John. Ich habe untersucht, wie die Komponente beim Rückruf aktualisiert werden kann, hatte aber nicht viel Glück. Hat das mit dem Staat zu tun? Ich bin immer noch ein Neuling zu reagieren! Ich habe den Code aktualisiert, um zu zeigen, wie die Komponente funktioniert. Können Sie mir sagen, wie die Daten beim Rückruf übergeben werden sollen? Danke noch einmal!
Desmond

@Desmond Ja, der Status kann funktionieren, da eine Komponente erneut gerendert wird, wenn sich ihr Status ändert.
John Weisz

4
zero-latency quantum-entanglement connection😂 Vielleicht ist es Zeit, diese zu erfinden, nur damit die Leute nicht mehr etwas über
Async

142

Ich habe versucht, dasselbe zu tun, und das hat bei mir funktioniert (ES6 / ES2015):

import myData from './data.json';

Ich habe die Lösung aus dieser Antwort in einem reaktionsnativen Thread erhalten, in dem das Gleiche gefragt wurde: https://stackoverflow.com/a/37781882/176002


11
Wenn Sie diese Methode mit Webpack verwenden, benötigen Sie json-loader für die importierten json-Dateien.
Kevr

3
Vielen Dank! Ich habe nach einer einfachen Möglichkeit gesucht, auf JSON-Daten in JSX zuzugreifen, und genau das ist es!
Matt Brand

6
Beachten Sie, dass dadurch Ihr JSON in das Bundle kompiliert wird und ein Hot-Swap-Austausch von JSON-Dateien unmöglich wird. Das ist wahrscheinlich für viele Anwendungsfälle in Ordnung, aber nicht für meine.
Wilson Biggs

Diese Antwort sollte als die genaueste Antwort markiert werden, aber mit json-loaderPaketbeispiel
Syed Aqeel

Hat für mich gearbeitet. Ich benutze Rollup. Zuvor hatte var data = import(‘./data.json’)das ein Versprechen importiert. Wenn Sie dies ändern, erhalten Sie import data from ‘./data.json’direkten Zugriff auf das importierte Objekt.
Max MacLeod

25

Der einfachste und effektivste Weg, eine Datei für Ihre Komponente verfügbar zu machen, ist folgender:

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

Beachten Sie das json!vor dem Pfad


3
Dies funktioniert nur, wenn Sie eine Bibliothek dafür hinzufügen. Da dies in React standardmäßig nicht unterstützt wird. Beispielbibliothek: - npmjs.com/package/json-loader
Gopinath Langote

2
json-loaderIch glaube, es ist in neueren Webpack-Versionen enthalten, aber Sie müssen möglicherweise noch etwas zu Ihrer Webpack-Konfiguration hinzufügen, um genau diese Syntax zu verwenden. Recherchiere danach.
agm1984

@ agm1984 Die Dinge haben sich seit 2015 geändert. Es wäre schön, wenn Sie stattdessen eine vollständige Antwort geben würden.
César D. Velandia

1
Ich glaube, die neuesten Webpack-Versionen enthalten json-loader, sodass Sie es nicht installieren oder in Ihrer Konfigurationsdatei deklarieren müssen. Ich würde empfehlen, nur zu versuchenimport FILE_AS_VARIABLE from './file/location.json'
agm1984


11
  1. installieren json-loader:

    npm i json-loader --save

  2. dataOrdner erstellen in src:

    mkdir data

  3. Legen Sie Ihre Datei (en) dort ab

  4. Laden Sie Ihre Datei

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


A hatte den Fehler "Kritische Abhängigkeit: Die Anforderung einer Abhängigkeit ist ein Ausdruck", wenn NICHT verwendet wird json!. Vielen Dank.
Secavfr

1
Gibt es überhaupt eine Möglichkeit, die JSON-Datei von außerhalb des src-Ordners zu verwenden? Ich benutze die
Create-React

8

Wenn Sie einige JSON-Dateien haben:

import data from 'sample.json';

Wenn Sie eine der vielen JSON-Dateien dynamisch laden möchten, müssen Sie möglicherweise fetchstattdessen Folgendes verwenden:

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

1

Mein JSON-Dateiname: 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"
      }
]

Importieren Sie zuerst oben:

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

dann nach der Rückkehr:

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

0

Sie können Ihre JSON-Datei mithilfe der Webpack-Konfiguration als externe Datei hinzufügen. Dann können Sie diesen JSON in eines Ihrer Reaktionsmodule laden.

Schauen Sie sich diese Antwort an


0

Wenn Sie die Datei als Teil Ihrer App-Funktionalität laden möchten, ist es am besten, diese Datei einzuschließen und auf sie zu verweisen.

Ein anderer Ansatz besteht darin, nach der Datei zu fragen und sie zur Laufzeit zu laden. Dies kann mit der FileAPI erfolgen . Es gibt auch eine andere Antwort von StackOverflow zur Verwendung: Wie öffne ich eine lokale Festplattendatei mit Javascript?

Ich werde eine leicht modifizierte Version für die Verwendung in React einfügen:

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>
    );
  }
}
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.