如何将数据从状态传递给道具?

时间:2019-07-08 09:10:24

标签: reactjs

我正在学习React,在使用状态和道具时遇到了一些麻烦。有两个文件:App.js和component。在App.js中,我使用axios从IP获取JSON数据并存储在状态中。但是我无法将数据通过状态传递给道具。 这是App.js:

import React from 'react';
import axios from 'axios';
import Shutruk from './Shutruk';

const qwerty = {
  "data": [
      {
          "_id": "5d1cb18e4af03042df6267c5",
          "title": "Shutruk",
          "description": "Shhhhhhhhhhhhh",
          "date": "2019-07-03T13:45:50.850Z",
          "__v": 0
      },
      {
          "_id": "5d1cc27b37c9751001f5c12f",
          "title": "Shilkhak",
          "description": "Shilkhak-Inshushinak",
          "date": "2019-07-03T14:58:03.797Z",
          "__v": 0
      },
      {
          "_id": "5d1cc45655780f11112a023f",
          "title": "Унташ",
          "description": "Untash-Napirisha",
          "date": "2019-07-03T15:05:58.699Z",
          "__v": 0
      },
      {
          "_id": "5d1ef36c503601183b5f856f",
          "title": "dgfdgfdhgf",
          "description": "bbbbbbbbbbbbbbbbb",
          "date": "2019-07-05T06:51:24.873Z",
          "__v": 0
      },
      {
          "_id": "5d1ef381503601183b5f8570",
          "title": "qewytuytruytru",
          "description": "jhfgasjdfgasjdfgjhsdf",
          "date": "2019-07-05T06:51:45.761Z",
          "__v": 0
      }
  ]
};
class App extends React.Component {
  state = {
    data: []
  }
  componentDidMount() {
    axios.get('http://localhost:5555/posts')
      .then(res => {
        const data = res.data;
        this.setState({ data });
      })
  }
  render() {
    return (
      <div>
        <Shutruk name={ this.state.data.data[0].title }/>
      </div>
    )
  }
}
export default App;

以下是组件:

import React from 'react';

class Shutruk extends React.Component {
  render() {
    return (
      <div>
        <h1>This is is {this.props.name}!</h1>
      </div>
    )
  }
}

export default Shutruk;

我使用axios从后端获取数据,但是当我将其插入道具时,它不起作用。我用相同的数据创建了一个数组qwerty [],当我替换为:

return (
  <div>
    <Shutruk name={ qwerty.data[0].title }/>
  </div>
)

它正常工作。如果“ this.state.data”和“ qwerty”之间没有区别,那是什么问题? 我检查了console.log,结果是一样的! 感谢大家的帮助!

3 个答案:

答案 0 :(得分:0)

只需更改此

<Shutruk name={ this.state.data.data[0].title }/>

使用

{this.state.data ? <Shutruk name={ this.state.data[0].title }/> : null}

更新

如果没有获取数据,则必须使用async/await

async componentDidMount() {
    await axios.get('http://localhost:5555/posts')
      .then(res => {
        //console.log(res) => if `res` is {data:[...]} , then do this,
        const data = res.data;
        //console.log(res) => if `res` is {data: data: [...]} , then do this,
        const data = res.data.data;
        this.setState({ data });
      })
  }

答案 1 :(得分:0)

这是因为axios和setState是异步的,并且当组件在componentDidMount中加载时,需要花费一些时间才能将数据加载到状态中,并且由于data.data [0]仍然为空,因此它不起作用。但是,当您使用const声明它时,它就已经存在了。

代替

<Shutruk name={ this.state.data.data[0].title }/>

要做:

  renderShutruk = () => {
    if (this.state.data.data !== undefined) {
      return <Shutruk name={this.state.data.data[0].title} />
    } else {
      return null;
    }
  };

  render() {
    return (
      <div>
        {this.renderShutruk()}
      </div>
    );
  }

答案 2 :(得分:0)

在访问未定义状态时,挂载时您的App组件可能崩溃,因为当this.state.data.data[0].title状态等于data时尝试获取[]

尝试像这样替换App组件,以防止访问未定义状态(建议对组件中的所有异步操作执行此操作):

class App extends React.Component {
  state = {
    data: [],
    loading: true,
    error: false,
  }
  componentDidMount() {
    axios.get('http://localhost:5555/posts')
      .then(res => {
        const data = res.data.data; // get the data array instead of object
        this.setState({ data, loading: false });
      })
      .catch(err => { // log request error and prevent access to undefined state
        this.setState({ loading: false, error: true });
        console.error(err); 
  }
  render() {
    if (this.state.loading) {
      return(
        <div>
          <p> Loading... </p>
        </div>
      )
    }
    if (this.state.error || !this.state.data[0]) { // if request failed or data is empty don't try to access it either
      return(
        <div>
          <p> An error occurred </p>
        </div>
      )
    }
    return (
      <div>
        <Shutruk name={ this.state.data[0].title }/> // access to data array state
      </div>
    )
  }
}
export default App;