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!

Desmond
quelle
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?

John Weisz
quelle
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

Rockfakie
quelle
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

César D. Velandia
quelle
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
Siehe Antwort hier: stackoverflow.com/questions/43735486/…
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');

ChaosPredictor
quelle
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))
jsbisht
quelle
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>
                  
Khadim Rana
quelle
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

Rishab Doshi
quelle
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>
    );
  }
}
bizi
quelle