简体   繁体   English

设置从axios到状态的响应

[英]Setting response from axios to state

When I try to setState after the get axios request it doesn't seem that I have the data ready to render.In console, I am getting a response but unable to access the response in the state. 当我在获取axios请求后尝试setState时,似乎我没有准备好渲染数据。在控制台中,我收到响应但无法访问状态中的响应。

import React, { Component } from 'react';
import axios from 'axios';
import { Grid, Row, Col } from 'react-flexbox-grid';
import Avatar from '@material-ui/core/Avatar';
import Button from '@material-ui/core/Button';
import stylefile from './stylefile';
import AppBar from '@material-ui/core/AppBar';
import Toolbar from '@material-ui/core/Toolbar';
import { withStyles } from '@material-ui/core/styles';
import '../App.css';

class TitleBar extends Component {
    constructor() {
        super();
        this.state ={
            data:[],
        }
      }

    componentDidMount() {
        axios.get('http://api.abc',
            {
                headers: { "Postman-Token": "abc"}
            })
            .then((response) => {
                console.log(response.data);
                this.setState({
                    data: response.data,
                })
            })
            .catch((error) => {
                console.log(error)
            })
    }

  render() {
    const { classes } = this.props;
    console.log(this.state.data,"data response")
    return (
        <div>
            {
                this.state.data.map(((item,key) => (
                 <div>
                     //
                 </div>
             )))}
        </div>
    );
  }
}

export default withStyles(stylefile)(TitleBar);
          console.log(error);
        });
    }

//console.log(this.state.data) -- is undefined //console.log(this.state.data) - 未定义

From React official docs , 来自React官方文档

componentWillMount() is invoked just before mounting occurs. 在安装发生之前调用componentWillMount()。 It is called before render(), therefore calling setState() synchronously in this method will not trigger an extra rendering 它在render()之前调用,因此在此方法中同步调用setState()不会触发额外的渲染

Also,one should use componentDidMount as componentWillMount is deprecated in new version of react. 同时,应该使用componentDidMount作为componentWillMount在反应的新版本过时。

componentDidMount() {
        axios.get('http://api./abc',
            {
                headers: { "Postman-Token": "abc" }
            })
            .then((response) => { //use arrow to get setState on this call without any extra binding or placeholder variable
                console.log(response.data);
                this.setState({
                    data: response.data,
                })
            })
            .catch((error) => {
                console.log(error)
            })
    }

Try to fix those lines of code: 尝试修复这些代码行:

  constructor(props) { //fixed
    super(props); //fixed
    this.state ={
        data:[],
    }
  }

This is just the way ReactJS set up the constructor() method for a class component . 这就是ReactJS为class component设置constructor()方法的方式。 We just obey the React's rules while working with it. 我们在使用它时只遵守React的规则。

From the Official React Document , they said: 来自官方反应文件 ,他们说:

The constructor for a React component is called before it is mounted. 在安装React组件之前,会调用它的构造函数。 When implementing the constructor for a React.Component subclass, you should call super(props) before any other statement. 在为React.Component子类实现构造函数时,应该在任何其他语句之前调用super(props)。 Otherwise, this.props will be undefined in the constructor, which can lead to bugs. 否则,this.props将在构造函数中未定义,这可能导致错误。

For more information about the contructor() method: https://reactjs.org/docs/react-component.html#constructor 有关contructor()方法的更多信息: https//reactjs.org/docs/react-component.html#constructor

This is a working example which I've already made just for you as a reference. 这是一个工作示例,我已经为您作为参考。

The demo is now available on CodeSandBox: https://codesandbox.io/s/8xvn8yl1l2 该示例现在可在CodeSandBox上获得: https ://codesandbox.io/s/8xvn8yl1l2

TitleBar.js

 import React, { Component } from 'react'; import axios from 'axios'; export default class TitleBar extends Component { constructor(props) { super(props); this.state = { data: [] }; } componentDidMount() { axios .get('https://jsonplaceholder.typicode.com/posts') .then(res => { console.log(res.data); this.setState({ data: res.data }); }) .catch(err => console.log(err.message)); } render() { return ( <div> {this.state.data.map(i => ( <div key={i.id}> <h2>{i.title}</h2> </div> ))} </div> ); } } 

App.js

 import React, { Component } from 'react'; import TitleBar from './components/TitleBar'; class App extends Component { render() { return ( <div> <TitleBar></TitleBar> </div> ); } } export default App; 

By following this example, if the this.state.data is still undefine , then there are two things that we could focus on in order to successfully debug: 通过以下示例,如果this.state.data仍未undefine ,那么为了成功调试,我们可以关注两件事:

1.The structure of the response data object. 1.响应数据对象的结构。 In your case, the solution could be 在您的情况下,解决方案可能是

this.setState({
   data: response.data.DATA  
})

2.Does the API work as expected. 2. API是否按预期工作。

Hopefully that helps. 希望这会有所帮助。

Your API response object includes an object like: 您的API响应对象包含一个对象,如:

const response = {
  data: {
    MESSAGE: "List details Fetch successful",
    STATUS: "SUCCESS",
    DATA: [
      { id: 1, name: "foo" },
      { id: 2, name: "bar" },
      { id: 3, name: "baz" }
    ],
    HASH: "3--0"
  }
};

So, you need response.data.DATA for your state here: 那么,你需要在你的州的response.data.DATA

this.setState( { data: response.data.DATA } );

Here is a working example of mimicking your situation. 这是一个模仿你的情况的工作例子。

 const remoteData = { data: { MESSAGE: "List details Fetch successful", STATUS: "SUCCESS", DATA: [ { id: 1, name: "foo" }, { id: 2, name: "bar" }, { id: 3, name: "baz" }, ], HASH: "3--0", }, }; const fakeRequest = () => new Promise( resolve => setTimeout( () => resolve( remoteData ), 1000 ) ); class App extends React.Component { state = { data: [], }; componentDidMount() { fakeRequest().then( response => this.setState( { data: response.data.DATA } ) ); } render() { return ( <div> {this.state.data.map( el => ( <div key={el.id}> <p>{el.id}</p> <p>{el.name}</p> </div> ) )} </div> ); } } ReactDOM.render( <App />, document.getElementById( "root" ) ); 
 <script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script> <div id="root"></div> 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM