Salmaan P
Salmaan P

Reputation: 857

React-Redux access props inside a nested object within component

I have a react-redux application and I am able to receive props inside a component.

This is my componentDidMount() function

componentDidMount() {
        this.graphdata = {

            dnsCountPlot: {
                data: [{
                    type: 'scatter',  
                    x: this.props.dnsCountPlot.x,
                    y: this.props.dnsCountPlot.y,
                    fill: 'tozeroy',
                    marker: {
                        color: 'rgb(99, 128, 185)'
                    }
                }],
                layout: {
                    title: '',
                    xaxis: {
                        title: 'time'
                    },
                    autosize: true

                },
                config: {
                    showLink: false,
                    displayModeBar: true
                }
            }

        };
}

The this.props.dnsCountPlot.x variable is updated every 10 sec and when I print the variable it shows that.

However the this.graphdata variable which contains the this.props.dnsCountPlot.x variable is not being updated. Any idea if this is possible and how to do it?

   componentDidUpdate() {

        console.log(this.props.dnsCountPlot.x); //Successfully Updated
        console.log(this.graphdata);            // Doesnt reflect changes of this.props.dnsCountPlot.x   

    }

the index.js file

const initialState = {
    dnsCountPlot : {
        x: [],
        y: []
    }
};
const store = createStore(reducers(initialState));

const history = createBrowserHistory();

startSocket(store);

ReactDOM.render((
    <Provider store={store}>
        <HashRouter history={history}>
            <Switch>
                <Route path="/" name="Home" component={Full}/>
            </Switch>
        </HashRouter>
    </Provider>
), document.getElementById('root'));

Thanks.

Upvotes: 0

Views: 621

Answers (1)

Eric Hodonsky
Eric Hodonsky

Reputation: 5897

You should set your initial state to have those props, then use the componentWillReceiveProps lifecycle method to update the state with this.setState( {...} ) which will redraw the component. Example:

constructor( props ){
    super();
    this.state = { ...props };
}
componentWillReceiveProps( nextProps ){
    this.setState( { ...nextProps } );
}
render(){
   <span>this.state.dnsCountPlot.x</span>
}

Or if you want:

constructor( props ){
    super();
    this.state = {
       graphData: {
         dnsCountPlot: {
            data: [{
                type: 'scatter',  
                x: this.props.dnsCountPlot.x,
                y: this.props.dnsCountPlot.y,
                fill: 'tozeroy',
                marker: {
                    color: 'rgb(99, 128, 185)'
                }
            }],
            layout: {
                title: '',
                xaxis: {
                    title: 'time'
                },
                autosize: true

            },
            config: {
                showLink: false,
                displayModeBar: true
            }
        }
      }
    };
}
componentWillReceiveProps( nextProps ){
    this.setState( { graphData: {
      ...this.state.graphData
      dnsCountPlot:{
        ...this.state.graphData.dnsCountPlot,
        data:[{
          ...this.state.graphData.dnsCountPlot.data[ 0 ],
          x: nextProps.dnsCountPlot.x,
          y: nextProps.dnsCountPlot.y,
        }] } } } );
}
render(){
   <span>this.state.graphData.dnsCountPlot.data[ 0 ].x</span>
}

---UPDATE---

It has been argued that setting the state with the props initially is an anti-pattern to React. And it even says so in the docs... HOWEVER, this stops being true if you complete this anti-pattern with an acceptable pattern of updating the state when those properties are updated on the component as done here in the componentWillReceiveProps lifecycle method.

Upvotes: 1

Related Questions