首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >将响应从axios设置为state

将响应从axios设置为state
EN

Stack Overflow用户
提问于 2018-09-27 18:23:20
回答 3查看 3.6K关注 0票数 1

当我在get axios请求之后尝试setState时,我似乎没有准备好数据到render.In控制台,我得到了一个响应,但无法在状态下访问该响应。

代码语言:javascript
复制
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) --未定义

EN

回答 3

Stack Overflow用户

发布于 2018-09-27 20:10:34

您的API响应对象包含如下对象:

代码语言:javascript
复制
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

代码语言:javascript
复制
this.setState( { data: response.data.DATA } );

这是一个模仿你的情况的工作示例。

代码语言:javascript
复制
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" )
);
代码语言:javascript
复制
<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>

票数 3
EN

Stack Overflow用户

发布于 2018-09-27 18:30:32

来自React official docs

componentWillMount()在挂载之前被调用。它是在render()之前调用的,因此在此方法中同步调用setState()不会触发额外的呈现

此外,由于componentWillMount在新版本的react中已被弃用,因此应该使用componentDidMount

代码语言:javascript
复制
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
EN

Stack Overflow用户

发布于 2018-09-27 19:04:13

尝试修复这些代码行:

代码语言:javascript
复制
  constructor(props) { //fixed
    super(props); //fixed
    this.state ={
        data:[],
    }
  }

这正是ReactJS为class component设置constructor()方法的方式。我们只是在使用React时遵守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

代码语言:javascript
复制
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

代码语言:javascript
复制
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.响应数据对象的结构。在您的情况下,解决方案可能是

代码语言:javascript
复制
this.setState({
   data: response.data.DATA  
})

2. API是否按预期工作。

希望这能有所帮助。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/52534815

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档