将响应从axios设置为state

时间:2018-09-27 10:23:20

标签: javascript reactjs axios

当我在获取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)-未定义

3 个答案:

答案 0 :(得分:1)

React official docs

  

componentWillMount()在安装发生之前被调用。它是在render()之前调用的,因此在此方法中同步调用setState()不会触发额外的渲染

此外,应该使用componentDidMount,因为新版本的react中不推荐使用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)
            })
    }

答案 1 :(得分:1)

尝试修复这些代码行:

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

这只是ReactJS为constructor()设置class component方法的方式。在使用它时,我们只是遵守React的规则。

他们从Official React Document说:

  

React组件的构造函数在挂载之前被调用。在为React.Component子类实现构造函数时,应在其他任何语句之前调用super(props)。否则,this.props将在构造函数中未定义,这可能会导致错误。

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

这是一个有效的示例,我已经为您提供了参考。

该演示现在可在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;

通过下面的示例,如果this.state.data仍然是undefine,那么为了成功调试,我们需要关注两件事:

1。响应数据对象的结构。就您而言,解决方案可能是

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

2。API是否按预期工作。

希望有帮助。

答案 2 :(得分:1)

您的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"
  }
};

因此,您需要response.data.DATA作为此处的状态:

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

这是模仿您的处境的有效示例。

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>