Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

React child component not re-rendering on parent state change

I am new to React, and looked through the similar questions in SO and couldn't find any. This maybe trivial but please bear with me.

I have nested components

const IndicatorsSteepCardContainer = React.createClass({
getInitialState () {

    return {
        steep: {
            Social: true,
            Tech: true,
            Economy: true,
            Ecology: true,
            Politics: true
        }, 

        data: indicatorData
    }
}

 render () {

    let props = this.props;
    let state = this.state;
    console.log('STATE inside steepcardcontainer >>>>', this.state.data);
    // VisualisationContainer to have different data eventually
    return (
        <div className="indicators">
            <h3 className="description-text">Tap on an issue group below to filter indicators available in the data visualisation. Tap it again to return to the full list of indicators.</h3>
            <div className='steep container steep-container'>
                <SteepCard selected={ this.selectedSteeps } steep="Social" data={ props.data.themeData } class="yellow" title="Social" steepIcon={ SocialIcon } />
                <SteepCard selected={ this.selectedSteeps } steep="Tech" data={ props.data.themeData } class="blue" title="Tech" steepIcon={ TechIcon }/>
                <SteepCard selected={ this.selectedSteeps } steep="Economy" data={ props.data.themeData } class="pink" title="Economy" steepIcon={ EconomyIcon } />
                <SteepCard selected={ this.selectedSteeps } steep="Ecology" data={ props.data.themeData } class="green" title="Ecology" steepIcon={ EcologyIcon } />
                <SteepCard selected={ this.selectedSteeps } steep="Politics" data={ props.data.themeData } class="orange" title="Politics" steepIcon={ PoliticsIcon }  />
            </div>
            <VisualisationContainer data={this.state.data}/>
        </div>
    );
}
});

Here is the render method in VisualisationContainer component:

render () {

  console.log('props inside visualisation-container>>>', this.props.data);

    return (
        <div className='visualisation-container'>
            <div className="render-button" onTouchTap= { this.d3It.bind(null, this.selectedSteeps) }>
                Plot graph
            </div>
            <div className="update-button" onTouchTap= { this.update.bind(null, this.selectedSteeps) }>
                Update
            </div>
            <div className="indicator-items">
                <IndicatorList data={this.props.data} className="indicator-list" />
                <SelectedIndicators visible={true} onClick={this.toggleVisibility}/>
            </div>

        </div>
    );
}

This component has another nested component inside it called IndicatorList, here is the code for that component:

render () {

    let props = this.props;
    let keys = Object.keys(props.data);
    console.log('props inside indicator-list>>>', props.data);
    let allIndicators = [];

    keys.forEach(function(key){
        var indicators = Object.keys(props.data[key]); 
        allIndicators.push(indicators);

        // console.log(allIndicators);

        });

    let merged = [].concat.apply([], allIndicators);

    return (
        <div className="indicator-list">

            {
                merged.map((val, i) => {
                    return <Indicator className="indicator-name" key={i} value={val} />
                })
            }
        </div>
    );
}

Finally, this component returns another component which is simply DIV elements that are dynamically generated based on the data in SteepCardContainer component.

 render () {

    return (
        <div> { this.props.value }</div>
    );
}

I am passing all the data used by these components via props from SteepCardContainer's state. Initially when the page is loaded the data is passed down and everything that is inside the state.data is used as the items in indicator component, which is the last nested component in the hierarchy. So, my problem is that on state change the props are not updated from the steepcardcontainer component. i.e. the state changes and I can see that, however the props aren't updated - in particular the VisualisatioContainer does not have its props updated, even though the state changed. That is the issue that I'm having. Any help is very much appreciated.

like image 297
Abdi Avatar asked Nov 20 '22 22:11

Abdi


1 Answers

The first thing I would do is.

 render () {

    let propsdThemeData = this.props.data.themeData;
    let stateData = this.state.data;
    console.log('STATE inside steepcardcontainer >>>>', this.state.data);
    // VisualisationContainer to have different data eventually
    return (
        <div className="indicators">
            <h3 className="description-text">Tap on an issue group below to filter indicators available in the data visualisation. Tap it again to return to the full list of indicators.</h3>
            <div className='steep container steep-container'>
                <SteepCard selected={ this.selectedSteeps } steep="Social" data={ propsdThemeData } class="yellow" title="Social" steepIcon={ SocialIcon } />
                <SteepCard selected={ this.selectedSteeps } steep="Tech" data={ propsdThemeData } class="blue" title="Tech" steepIcon={ TechIcon }/>
                <SteepCard selected={ this.selectedSteeps } steep="Economy" data={ propsdThemeData } class="pink" title="Economy" steepIcon={ EconomyIcon } />
                <SteepCard selected={ this.selectedSteeps } steep="Ecology" data={ propsdThemeData } class="green" title="Ecology" steepIcon={ EcologyIcon } />
                <SteepCard selected={ this.selectedSteeps } steep="Politics" data={ propsdThemeData } class="orange" title="Politics" steepIcon={ PoliticsIcon }  />
            </div>
            <VisualisationContainer data={stateData}/>
        </div>
    );
}
like image 200
J. Mark Stevens Avatar answered Dec 09 '22 19:12

J. Mark Stevens