【问题标题】:reactjs - fetching data from apireactjs - 从 api 获取数据
【发布时间】:2017-07-03 01:01:24
【问题描述】:

我对 ReactJS 还很陌生,在伟大的 SO 社区的帮助下,我一直在构建一个小练习,通过单击在两个组件之间来回移动项目。这些项目来自我硬编码到文件中的 json 数组 items=[] 中的数据。我想知道如何从 api 获取数据,我已经阅读了文档并且知道我应该通过 componentDidMount 方法来做到这一点,但是我在弄清楚如何在方法中设置状态时遇到了困难。代码如下...

class SingleItem extends React.Component {
render() {
    let data = this.props.data;

    return (
        <li onClick={this.props.onClick}>
            <div> {data.name} </div>
        </li>
    );
  }
}

class ItemList extends React.Component {
   render() {
    let itemArr = this.props.allItems;
    let myItems = this.props.items;
    let handleEvent = this.props.handleEvent;

    let listItems = itemArr.map((itemObj) => {
        if (!myItems.includes(itemObj.id)) return null;

        return <SingleItem
            key={itemObj.id}
            data={itemObj}
            onClick={() => handleEvent(itemObj.id)}
        />;
    });

    return (
        <ul>
            {listItems}
        </ul>
    );
  }
}

 class App extends React.Component {
   constructor(props) {
     super(props);

     this.state = {
        data: [],
        boxOne: props.items.map(item => item.id), // init the boxes with 
 itemIds
        boxTwo: []
    };

    this.handleEvent = this.handleEvent.bind(this);
}

handleEvent(itemId) {
    const isInBoxOne = this.state.boxOne.includes(itemId);

    // Heres the magic, if the item is in the first Box, filter it out,
    // and put into the second, otherwise the other way around..
    this.setState({
        boxOne: isInBoxOne
            ? this.state.boxOne.filter(i => i !== itemId)
            : [ ...this.state.boxOne, itemId ],
        boxTwo: isInBoxOne
            ? [ ...this.state.boxTwo, itemId ]
            : this.state.boxTwo.filter(i => i !== itemId)
    });
}
render() {
    return (
        <div className="wrapper">
            <div className="box">
                <ItemList handleEvent={this.handleEvent} items={this.state.boxOne} allItems={this.props.items} />
            </div>
            <div className="box">
                <ItemList handleEvent={this.handleEvent} items={this.state.boxTwo} allItems={this.props.items} />
            </div>
        </div>
    );
  }
 };

var items = [
  {name: "Item 1", id: 1},
  {name: "Item 2", id: 2},
  {name: "Item 3", id: 3},
  {name: "Item 4", id: 4},
  {name: "Item 5", id: 5},
  {name: "Item 6", id: 6}
 ]

ReactDOM.render(
   <App items={items} />,
   document.getElementById('root')
 );

【问题讨论】:

    标签: javascript reactjs


    【解决方案1】:

    您可以使用axios轻松做到这一点

    componentDidMount() {
      axios.get('http://myapi.com/myrequest')
        .then((res) => {       
          this.setState({ data:res.myvalue }); // change state
      })
    }
    

    但是,要使用组件之间的“全局状态”、专用 API 等来制作更复杂的应用程序。您应该使用 ReduxMeteor

    【讨论】:

    • 谢谢!那么这是否意味着我应该将BoxOne:this.state: 更改为一个空数组,因为我现在将在componentDidMount() 方法中使用props.items.map(item =&gt; item.id) 设置状态?
    • 我认为你不应该直接在构造函数中获取 boxOne(和 Two),而是使用 componentWillMount() 来代替 getBox(num){ /*return the num box*/ } 之类的函数
    【解决方案2】:

    您好,您可以使用 fetch api from java script 进行 api 调用,也可以使用 promise 来处理结果。

    【讨论】:

      【解决方案3】:

      您可以直接在componentDidMount 中调用您的HTTP 是的。但是随着您的应用程序的增长,您将希望将此逻辑与组件隔离开来。因此,您的组件将更具可重用性和可维护性。只需等待承诺兑现,然后再用结果设置您的状态。

      axios.get('/api/url')
        .then(function (response) {
          this.setState({data: response.data})
        })
        .catch(function (error) {
          this.setState({data: [], error: true})
        })
      

      关于发出 HTTP 请求的库,您可以使用 axiossuperagent。无论如何,我建议您使用在服务器和客户端站点上都可以使用的库。因此,如果您希望您的应用程序是同构/通用的(由 nodeJS 服务器呈现),您将不会遇到麻烦。

      【讨论】:

      • 然后我会在我的 &lt;App /&gt; 父组件中调用什么来从 API 访问数据?例如,在我的渲染方法中我有App items={items},我现在要放什么?
      • 我很清楚你的意思,但如果你需要层次结构中的上述数据,你应该调用 API 并将结果提供给 App 父级中的状态。然后你用道具把数据传给孩子们。
      猜你喜欢
      • 1970-01-01
      • 2021-05-22
      • 2019-03-25
      • 2016-11-27
      • 1970-01-01
      • 1970-01-01
      • 2021-02-07
      • 2021-09-29
      • 2023-03-08
      相关资源
      最近更新 更多