最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - ReactJS get XMLHttpRequest not working - Stack Overflow

programmeradmin4浏览0评论

I'm trying to get XML-Data from an XML-file and want to save certain node values in a list. This is how I tried to do it:

import React from "react";

class EditFiles extends React.Component {
    constructor(props) {
        super(props);
        this.loadXML = this.loadXML.bind(this);
    }

    loadXML = () => {

        var xhttp = new XMLHttpRequest();

        xhttp.onreadystatechange = function() {
            if (this.readyState == 4 && this.status == 200) {

                var xmlDoc = this.responseXML;
                var y = xmlDoc.getElementsByTagName("newFile");

                for(var i=0; i<y.length; i++) {

                    var NameArray = [y[i].getElementsByTagName("FileName")[0]];
                }

                const nameList = NameArray.map(name => 
                    <li>{name}</li>
                );
            }
        };

        xhttp.open("GET", "./FilenameList.xml", true);
        xhttp.send();

    }

    render() {
        return(
            <ul>{nameList}</ul>
        );
    }
}

First of all, I don't know if it can even be done this way. I did find similar questions, however, the code in the answers was not explained very well and I don't want to just copy and paste some code without understanding it (also, even if I wanted to do that, I probably couldn't, since I wouldn't know what represents what. The error I'm getting with this code is that nameList is not defined in the render function. I know that it would have to be a global function, but I do not know how to do that.

I also read this post: /@catquarks/making-ajax-requests-with-react-48be0285d396 and wanted to do it like in the example. But I don't quite understand it, for example, how would I get the value of certain tags?

Anyway, to sum up my goal for this question: Can I use an XMLHttpRequest the way I did and what mistakes did I make exactly?

I hope this isn't all over the place. If you need further information/explanation please let me know.

Quick Edit: the XML-file looks kinda like this:

<Files>
    <newFile>
        <FileName>file1</FileName>
    </newFile>
    <newFile>
        <FileName>file2</FileName>
    </newFile>
</Files>

What I would also like to note, is that the xml-file is created dynamically, therefore it's not predictable how many newFile nodes there are going to be.

I'm trying to get XML-Data from an XML-file and want to save certain node values in a list. This is how I tried to do it:

import React from "react";

class EditFiles extends React.Component {
    constructor(props) {
        super(props);
        this.loadXML = this.loadXML.bind(this);
    }

    loadXML = () => {

        var xhttp = new XMLHttpRequest();

        xhttp.onreadystatechange = function() {
            if (this.readyState == 4 && this.status == 200) {

                var xmlDoc = this.responseXML;
                var y = xmlDoc.getElementsByTagName("newFile");

                for(var i=0; i<y.length; i++) {

                    var NameArray = [y[i].getElementsByTagName("FileName")[0]];
                }

                const nameList = NameArray.map(name => 
                    <li>{name}</li>
                );
            }
        };

        xhttp.open("GET", "./FilenameList.xml", true);
        xhttp.send();

    }

    render() {
        return(
            <ul>{nameList}</ul>
        );
    }
}

First of all, I don't know if it can even be done this way. I did find similar questions, however, the code in the answers was not explained very well and I don't want to just copy and paste some code without understanding it (also, even if I wanted to do that, I probably couldn't, since I wouldn't know what represents what. The error I'm getting with this code is that nameList is not defined in the render function. I know that it would have to be a global function, but I do not know how to do that.

I also read this post: https://medium./@catquarks/making-ajax-requests-with-react-48be0285d396 and wanted to do it like in the example. But I don't quite understand it, for example, how would I get the value of certain tags?

Anyway, to sum up my goal for this question: Can I use an XMLHttpRequest the way I did and what mistakes did I make exactly?

I hope this isn't all over the place. If you need further information/explanation please let me know.

Quick Edit: the XML-file looks kinda like this:

<Files>
    <newFile>
        <FileName>file1</FileName>
    </newFile>
    <newFile>
        <FileName>file2</FileName>
    </newFile>
</Files>

What I would also like to note, is that the xml-file is created dynamically, therefore it's not predictable how many newFile nodes there are going to be.

Share Improve this question asked Dec 14, 2017 at 9:07 A.S.JA.S.J 6374 gold badges16 silver badges40 bronze badges
Add a ment  | 

1 Answer 1

Reset to default 3

You need to tell React how and when to execute the code in your loadXML function. Binding it like you did in the constructor is useless here, as bind simply changes the this keyword for the loadXML function. And actually, React es with a set of functions you should use instead, as loadXML's purpose is to fetch data from an external source.

In your case, ponentDidMount is the right place to execute the code instructions of loadXML.

A best practice is to :

  • set your initial state in the contructor() function
  • load external data (what you do with XMLHttpRequest in the ponentDidMount() function

More generally, the React Component Lifecycle is a very insightful source to understand the various functions that are executed when displaying and updating a React ponent. You may find this example useful too.

One your data has been loaded, then update the state of your ponent with the data you obtain. Updating the state (or props) of a React ponent automatically triggers its render() function and display your changes.

Then, in the render() function, just return the DOM elements (or React ponents) to display based on the ponent's state variable. In the following example, we download JSON data (posts) from a URL using XMLHttpRequest and return the title of each post. We tell render() to check the length of the posts array in order to know if we have posts to display.

You can run the code snippet directly, data is JSON based (not XML), but I'm sure you can adapt it to your case.

class EditFiles extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
          posts: []
        }
    }

    ponentDidMount() {
      var xhttp = new XMLHttpRequest();
      var self = this;
      
      xhttp.onreadystatechange = function(e){
        console.log(this);
        if (xhttp.readyState === 4 && xhttp.status === 200){
          console.log("ok, response :", this.response);
          self.setState({
            posts: JSON.parse(this.response)
          });
        }
      }
      xhttp.open("get", "https://jsonplaceholder.typicode./posts", true);
      xhttp.send();
    }

    render() {
      let postsLoaded = this.state.posts.length > 0;
      return(
        postsLoaded ?
          <ul>
          {
            this.state.posts.map(
              post => {
                return <li>{ post.title }</li>;
              })
          }
          </ul>
          :
          <div>Loading...</div>
      );
    }
}

ReactDOM.render(
  <EditFiles />,
  document.getElementById('container')
);
<script src="https://cdnjs.cloudflare./ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare./ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="container">
    <!-- This element's contents will be replaced with your ponent. -->
</div>

Hope this helps!

发布评论

评论列表(0)

  1. 暂无评论