如何在div元素中呈现更新后的状态?

时间:2019-08-10 15:24:57

标签: javascript reactjs react-native jsx

我将按钮设置为:

  1. 对GET数据进行API调用,并列出其中的标题 数据;
  2. 退回这些标题;
  3. 使用这些标题更新组件的“文本”状态
  4. 在div中显示这些标题

所有这些事情似乎都在发生;但是也许顺序不对?我可以说this.state.text使用标题进行了更新,但是DOM没有收到更新的状态。我已经以可以在样板React应用程序的'index.js'文件中运行的格式附加了代码。

我尝试弄乱操作顺序,将getAllPosts()函数输出为数组,并进行无数的Array操作。

import React from 'react';
import ReactDOM from 'react-dom';



class AllPosts extends React.Component {
    constructor(props) {
      super(props);
      this.state = {text: 'poop'};
    }

    getAllPosts(){
      var request = new XMLHttpRequest();
      var titles=[];
      request.open('GET', 'http://jsonplaceholder.typicode.com/posts', true)
      request.onload = function () {
        var data = JSON.parse(this.response);   
        if (request.status >= 200 && request.status < 400) {
          data.forEach(post => {
            titles.push(post.title);
          })
        } else {
          console.log('error getting title list.  Please try again.');
        }
      }
      request.send();
      console.log(titles);
      return titles;
    }  

    onClickButton = () => {
      var allTitles = this.getAllPosts();
      this.setState({text: allTitles});
      console.log(this.state.text);
      console.log(this.allTitles);  
    }  

    render() {
      return (
        <div>
        <button
          onClick={this.onClickButton}>
            Get All Posts
        </button>
        <div>{this.state.text}</div>
        </div>
      );
    }
  }

  function App() {
    return (      
      <div className="App">
        <header className="App-header">

          <AllPosts />
        </header>
      </div>
    );
  }

  export default App;

ReactDOM.render(<App />, document.getElementById('root'));

(已打开控制台) 预期结果是div文本在单击时发生了更改,从“便便”更改为标题列表。发生的情况是数据“未定义”并且文本被清空。再次单击该按钮时,当我要求它记录this.state.text时,标题列表将在控制台中填充,因此很显然进入了状态。但是状态不会在页面上更新。

3 个答案:

答案 0 :(得分:1)

您需要将l = ['Tom', 'Michael', 'Tom', 'Tom'] res = [] d = {} for x in l: res.append(x + " "*d.setdefault(x, 0)) d[x] += 1 包裹在一个约定中:

XMLHttpRequest

您的getAllPosts = () => { new Promise((resolve, reject) => { var request = new XMLHttpRequest(); var titles = []; request.open('GET', 'http://jsonplaceholder.typicode.com/posts', true) request.onload = function () { var data = JSON.parse(this.response); if (request.status >= 200 && request.status < 400) { data.forEach(post => { titles.push(post.title); }) resolve(titles); } else { reject('error getting title list. Please try again.'); } } request.send() }).then(titles => { this.setState({ allTitles: titles }) }).catch((error) => { console.log(error) }) } 现在应该只调用getAllPosts(),什么都不要。

onClickButton()

答案 1 :(得分:0)

使用Axios进行API调用,它将使您的代码更简单易用,并且在视觉上更具吸引力。

如果对代码有任何疑问,请发表评论。 这是Axios的文档。

import React from 'react';
import ReactDOM from 'react-dom';
import axios from 'axios';



class AllPosts extends React.Component {
    constructor(props) {
      super(props);
      this.state = {text: 'foo'};
    }

    async getAllPosts () {
      var titles = [];

      const response = await axios.get('http://jsonplaceholder.typicode.com/posts')
      const data = response.data;

      data.forEach((post) => {
          titles.push(post.title);
      })

      return titles;
    }  

    onClickButton = async () => {
      var allTitles = await this.getAllPosts();

      this.setState({ text: allTitles });
    }  

    render() {
      return (
        <div>
        <button
          onClick={this.onClickButton}>
            Get All Posts
        </button>
        <div>{this.state.text}</div>
        </div>
      );
    }
  }

  function App() {
    return (      
      <div className="App">
        <header className="App-header">

          <AllPosts />
        </header>
      </div>
    );
  }

  export default App;

  ReactDOM.render(<App />, document.getElementById('root'));

答案 2 :(得分:0)

您可以将请求包装在Promise中,然后从promise函数返回getAllPosts

getAllPosts = () => {
  return new Promise((resolve, reject) => {
    var request = new XMLHttpRequest();
    var titles = [];
    request.open('GET', 'http://jsonplaceholder.typicode.com/posts', true)
    request.onload = function() {
      var data = JSON.parse(this.response);
      if (request.status >= 200 && request.status < 400) {
        data.forEach(post => {
            titles.push(post.title);
        })
        resolve(titles);
      } else {
        console.log("fail")
        reject('error getting title list.  Please try again.');
      }
    }
    request.send();
  })
}

您的onClickButton函数应该是

onClickButton = () => {
  let allTitles = this.getAllPosts();
  allTitles.then(titles => {
     console.log("success");
     this.setState({ text: titles })
  }).catch((error) => { 
     console.log(error)
  })
}

另一种简单的方法是使用fetch

getAllPosts = () => {
  fetch("http://jsonplaceholder.typicode.com/posts")
    .then(response => response.json())
    .then(titles => {
      console.log("success");
      let title = [];
      titles.forEach(post => {
          title.push(post.title);
      })
      this.setState({ text: title })
    }).catch((error) => {
        console.log(error)
    })
}

您的onClickButton函数应该是

onClickButton = () => {
   this.getAllPosts();
}