简体   繁体   English

从存储中调用api,并将数据绑定到ReactJS / flux中的组件状态

[英]Call api from a store and bind data to component state in ReactJS/flux

Using React-router-component, i have set to load my home page with a component called gigist which is as folows: 使用React-router-component,我已经设置为用一个名为gigist的组件加载我的主页,如下所示:

var React = require('react');
var AppStore =require('../../stores/app-store.js');
var GigsListItem = require('./giglistitem.js');
var StoreWatchMixin =require('../../mixins/StoreWatchMixin.js');

function getGigs()
{

    return {items:AppStore.getGigs()}
}

var GigsList= React.createClass({
  mixins:[new StoreWatchMixin(getGigs)],
  componentWillMount:function()
  {
     this.setState(getGigs());
     console.log(this.state);
  },
  componentDidMount:function()
  {
     this.setState(getGigs());
     console.log(this.state);
  },
    render:function()
    {
        console.log("rendered view");
        var liststyle={border:'1px solid black'};

        /*
        var items=this.state.items.map(function(item)
        {
            return <GigsListItem gig={item} />
        })  */
        return (

                <div className="row" style={liststyle}>
                {this.state.items}

                </div>
               )
    }
});

module.exports=GigsList;

I am making an ajax call using npm reqwest,but the problem is that the view is being rendered and setting its state to undefined before completion of ajax request. 我正在使用npm reqwest进行ajax调用,但是问题是在ajax请求完成之前,正在渲染视图并将其状态设置为undefined。 You can see it from my console log 您可以从我的控制台日志中看到它 从consoe来看,“ 1”是为组件giglist设置初始状态,“ 3”是将要安装组件,“ rendered view”是在渲染组件时,“ 2”用于ajax请求

From the console '1' is at setting initial state for component giglist,'3' is component will mount,'rendered view' is while rendering component,'2' is for the ajax request 在控制台中,“ 1”正在设置组件giglist的初始状态,“ 3”是将安装组件,“ rendered view”是在渲染组件时,“ 2”用于ajax请求

which clearly states that data is not being set to component state after the ajax call. 明确指出在ajax调用之后,数据未设置为组件状态。

I need to set state for the component after i get response from it. 得到响应后,我需要为组件设置状态。 I tried setting state with componentwillmount and componentdidmount but neither solve my issue. 我尝试使用componentwillmount和componentdidmount设置状态,但是都不能解决我的问题。

here is my store code: 这是我的商店代码:

var AppDispatcher = require('../dispatchers/app-dispatcher');
var AppConstants = require('../constants/app-constants');
var reqwest = require('reqwest');
var merge = require('react/lib/merge');
var EventEmitter = require('events').EventEmitter;

var CHANGE_EVENT = "change";

var _gigs = [];

function getGigsList()
{

reqwest({url:'myapi',
type:'get',
success:function(resp)
{
  console.log(2);
  return resp.gigs;  
  //alert(JSON.stringify(_gigs));
}.bind(this)})  


}  



var _cartItems = [];


function _removeItem(index){
  _cartItems[index].inCart = false;
  _cartItems.splice(index, 1);
}

function _increaseItem(index){
  _cartItems[index].qty++;
}

function _decreaseItem(index){
  if(_cartItems[index].qty>1){
    _cartItems[index].qty--;
  }
  else {
    _removeItem(index);
  }
}


function _addItem(item){
  if(!item.inCart){
    item['qty'] = 1;
    item['inCart'] = true;
    _cartItems.push(item);
  }
  else {
    _cartItems.forEach(function(cartItem, i){
      if(cartItem.id===item.id){
        _increaseItem(i);
      }
    });
  }
}

function _CartTotals()
{
  var qty=0,total=0;
  _cartItems.forEach(function(cartItem)
    {
       qty+=cartItem.qty;
       total+=cartItem.cost * cartItem.qty;

    });
  return {'qty':qty,'total':total}
}


var AppStore = merge(EventEmitter.prototype, {
  emitChange:function(){
    this.emit(CHANGE_EVENT)
  },

  addChangeListener:function(callback){
    this.on(CHANGE_EVENT, callback)
  },

  removeChangeListener:function(callback){
    this.removeListener(CHANGE_EVENT, callback)
  },

  getCart:function(){
    return _cartItems
  },

  getGigs:function(){
    alert(JSON.stringify(getGigsList()));
    return getGigsList();
  },

  getCartTotals:function()
  {
    return _CartTotals();
  },

  dispatcherIndex:AppDispatcher.register(function(payload){
    var action = payload.action; // this is our action from handleViewAction
    switch(action.actionType){
      case AppConstants.ADD_ITEM:
        _addItem(payload.action.item);
        break;

      case AppConstants.REMOVE_ITEM:
        _removeItem(payload.action.index);
        break;

      case AppConstants.INCREASE_ITEM:
        _increaseItem(payload.action.index);
        break;

      case AppConstants.DECREASE_ITEM:
        _decreaseItem(payload.action.index);
        break;
    }
    AppStore.emitChange();

    return true;
  })
})

module.exports = AppStore;

can somebody point out where i am doing wrong.I hope i am clear.Thanks in advance 有人可以指出我做错了什么吗?我希望我说清楚。谢谢

You cannot use return statements in asynchronous code, ie, in the success callback of your ajax-call. 您不能在异步代码中(即,在ajax调用的成功回调中)使用return语句。

Instead, try to check if there are already gigs in the store, in which case you return them, and if there are no gigs in the store you do a request to get some and in the success callback you set the store state to the new data and emit a change that will tell your component to try to fetch the store state again. 相反,尝试检查商店中是否已经有演出,在这种情况下,您将它们退回,如果商店中没有演出,则请求获取一些演出,并在成功回调中将商店状态设置为新数据并发出更改,该更改将告诉您的组件尝试再次获取存储状态。

    function getGigsList()
    {
        if (_gigs.length > 0) { return _gigs; } //return immediately if data exists

        reqwest({url:'myapi',
        type:'get',
        success:function(resp)
        {
            console.log(2);
            _.gigs = resp.gigs;  
            this.emit(CHANGE_EVENT);
        }.bind(this)}) 

        return _gigs; //currently an empty array. this way you don't have to check for undefined in the component, you can just iterate over it directly
    }  

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

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