Search code examples
reactjsfluxreactjs-fluxrefluxjs

How to setState to one particular component instance in RefluxJS?


I'm currently doing one small project in React + Flux (RefluxJS) and I faced wit one issue I can't solve. I would be very gratefully if someone of you can give me a hand.

Here you have the link to GitHub with the whole project in order to facilitate your help, it's a simplest version just to reproduce the problem I faced.

My doubt is, how can I use one component in the same view with different content. Let me explain:

I have on component in, "components/threads.jsx" which in summary render this peace of code getting the data from the store ("stores/thread-store.jsx") throug a fake API ("utils/api.jsx"):

renderThreads: function() { 
    return this.state.thread_content.map(function(thread, i) {  
        return (
            <div key={thread.id}>
                <div className="row">
                    <div className="col-md-10">
                        <a data-toggle="collapse" href={'#thread-' + thread.id} className="faq-question">{thread.name}</a>: <small>{thread.content}</small>
                    </div>              

                </div>
                <div className="row">
                    <div className="col-lg-12">
                        <div id={'thread-' + thread.id} className="panel-collapse collapse ">
                            <Posts id={thread.id} />
                        </div>
                    </div>
                </div>
            </div>
        );

    });
},

As yo can see, I have another component nested called "Posts" in "components/thread-posts.jsx" which is rendered for each thread is mapped. In the "Posts" component I have this peace of code:

module.exports = React.createClass({
mixins: [
    Reflux.listenTo(PostsStore, 'onChange'),
],
getInitialState: function() {
    return {
        posts: []
    }
},
componentDidMount: function() {
    Actions.getPosts(this.props.id);
},
render: function() {    
    return (
        <div>
            {this.renderPosts()}
        </div>
    );
},
renderPosts: function() {
    if(this.state.posts.comments != undefined){
        return this.state.posts.comments.map(function(post, i) {
            return(                             
                <div key={i} className="faq-answer">
                    <p>             
                    {post.content}
                    </p>
                </div>
            );
        });
    }
},
onChange: function(event, posts) {
    this.setState({
        posts: posts,
    });
}

Here comes the problem. When finish the render, all the threads have the same posts, in particular the lasts ones were set. I think is related with the states, if they change it will be change in all the components were rendered.

So, my question is, how can I deal with it in order to have the posts according to its thread but using the same component? If it's not posible, which is the best solution to do that?

I hope explained myself as well as enough to understand me.

I will be very gratefully if you can give me a hand in this issue.

Thanks in advance.


Solution

  • Yes if you share the Store with your View then latest one will be overwrite your previous Component's data

    you have to create a separate variable which can hold the data of each API Call and when call API you have to pass the Key like

    let's take one example

    I have one Component it's called MainComponent I want to use same Component on same page twice but the data should be different for both component I have one Store for MainComponent called MainStore In MainStore I have one Method called getData like

    getData:function(key)
    {
     //API Call
    }
    

    now I am calling this method from my MainComponent from componentDidMount event like

    componentDidMount:function()
    {
      //if you used Action then you have to called like 
       MainComponentAction.getData(this.props.Key);
      // if you directly called 
      MainComponentStore.getData(this.props.Key);
    }
    

    here this.props.Key you have to pass from the parent component which should 1 or 2

    now come to store we have passed the Key so now we have to check condition while we received a data from API

    suppose I have taken one variable in which I am storing the data which is return by API like

    now you have to create two methods for store the data based on key var _data,_data1

    function loaddata(APIdata,key)
        {
         if(key===1)
           {
             _data=APIdata
            }
        else
         {
           _data1=APIdata
         }
    
        }
    

    and in your store you to methods for getting the data like

    getData:function()
    {
    return _data;
    },
    getData1:function()
    {
    return _data1;
    }
    

    now your getintialState of MainComponent Should be

    getintialState:function()
    {
    return{
       Data:JSON.Parse(MainComponentStore.getData()),
       Data1:JSON.Parse(MainComponentStore.getData1()),
      }
    }
    

    and your MainComponent render function should be

     render:function(){
        var LatestData;
        if(this.props.Key===1)
        {
        LatestData=this.state.Data
        }
        else if(this.props.Key===2)
        {
        LatestData=this.state.Data1
        }
    return(
      <div>
       {LatestData}
      </div>
    )
        }