0

I'm writing my first reactjs + flux application and I have managed to get the basic code working. However, there is a list, which populates another list depending on which list item is clicked. This was working fine until I had my list data hard-coded in the store. But when I started getting the data for the list items from the server, the second list does not get populated on a single click - it needs two clicks to do that. I don't think that getting data from server is a problem because the default data is populated correctly. After debugging, I found out that the store is also returning the data correctly, but the setState() is not setting the data. What am I doing wrong? Here's my code:

function getInitialData(){
    return{
        items:DataStore.getFirstItemData()
    }
}

var ListItems = React.createClass({
    getInitialState:function(){
        return getInitialData();
    },
    _onChange:function(){
        this.setState(getInitialData);
    },
    componentDidMount:function(){
        DataStore.addChangeListener(this._onChange);
    },
    componentWillReceiveProps:function(){

        this.setState({items:this.props.itemsData});    

    },
    handleClick:function(e)
    {
        var data = DataStore.getSubItemsFor(e);
        this.setState({items:data});

    },
    render:function(){
        return(

            <div>
            <div className="col-md-3 dc-left" id="main-list">
                <div className="dc-main-list-parent">
                    {this.props.listData.map(function(list_items){
                        return(
                                <div key={list_items.id}  onClick = {this.handleClick.bind(this,list_items.id)}>
                                </div>
                            );
                    },this)}        
                </div>
            </div>
            <div className="col-md-9 dc-center" id="sub-list">
                <SubList sublistData = {this.state.items} />
            </div>

            </div>
            )
    }
});

P.S. This code has been modified a little for posting here. Please overlook any syntactical errors - it works!

user4773422
  • 75
  • 1
  • 2
  • 6
  • Could you provide a JSBin/JSFiddle which reproduces the problem? – Anders Ekdahl May 21 '15 at 06:53
  • @Anders I wish I could! But this is one component out of 6, and server is on localhost. – user4773422 May 21 '15 at 06:59
  • 2
    @user4773422 you shouldn't set the data directly after sending the action to the store, the store should be responsible for cascading the data down to your component. – Henrik Andersson May 21 '15 at 07:41
  • @limelights Since my items is just a getter, I figured I wouldn't need any actions for that.Anyway, I tried dispatching an action but got a 'Cannot dispatch in the middle of a dispatch' error. How do I get the items variable to set after the previous dispatch is complete? – user4773422 May 21 '15 at 08:07

1 Answers1

0

Probably things break down because updates to the DataStore trigger 2 changes:

  1. The complete component gets rerendered by the parent component, which fires the componentWillReceiveProps + fires a render cycle.
  2. You also have a listener to changes in the DataStore, so the update in the DataStore also fires the _onChange event, which tries to update the state as well

PS: the code has a typo:

this.setState(getInitialData);

should read:

this.setState(getInitialData());

I would suggest you remove the change listener part, and see if that helps..

wintvelt
  • 13,855
  • 3
  • 38
  • 43