Search code examples
reactjsredux

How can we modify component state as well when an action is dispatched?


`

import React, {Component} from 'react';
import {connect} from 'react-redux';
import Chart from '../components/chart.js';
import GoogleMap from '../containers/googlemap';
import {removeCityMap} from '../actions/index';
import { bindActionCreators } from "redux";
import AttributeSelector from './attributeselector'

class WeatherBoard extends Component{
    constructor(props){
        super(props);
        this.state = {
            chartData1: []
        }
    }
    weatherAttrMapper(attrName){
        //Setting the state which is based on the data received from action dispatched.
        this.setState({
            chartData1:this.props.weather[0].list.map(weather => weather.main[attrName])
        })
    }
    renderMapList(cityData){
        //Based on the weather prop received when action is dispached I want to set the state before rendering my <chart> element.
        this.weatherAttrMapper('temp');
        return(
            <tr key = {cityName}>
                <td><Chart data = {this.state.chartData1} color = "red" units="K"/></td>
            </tr>
        )
    }
    render(){
        return(
            <table className="table table-hover">
                <tbody>
                    {this.props.weather.map(this.renderMapList.bind(this))} 
                </tbody>
            </table>
        )
    }
}
//This is the weather state coming from my reducer which is being used here.
function mapStateToProps({ weather }) {
    return { weather };
}
function mapDispatchToProps(dispatch) {
    return bindActionCreators({ removeCityMap }, dispatch);
}
  
export default connect(mapStateToProps,mapDispatchToProps)(WeatherBoard);

`I have a doubt regarding state management.

Problem statement: I have a container abc.JS file which is mapped to redux state by mapStateToProps. I have a action handler on button click which fetches data from API. When my actionhandler is dispatched it hits my render method in abc.js. Now my ask is I am maintaining state in abc.js as well which is also being used in render method and this need to be modified when action is dispatched. So how can I setstate my abc.js state which could also be rendered.

I have also added the exact code snippet of my abc.js. So basically I enter my render method when action is dispatched and I here I need to setstate somehow.

Thanks.


Solution

  • It depends what you need to do, if you just need to dispatch an action and set the state "at the same time" then something like this would work:

    ...
      handleOnClick = () => {
        this.props.actions.myAction();
        this.setState({ myStateField: "myNewValue" });
      }
    
      render() {
        return (
          <div>
            <h1>MyContainer</h1>
            <button onClick={this.handleOnClick}>Click me</button>
          </div>
        );
      }
    

    If instead you need to dispatch an action then based on how the state in your manager is updated you need to also update the state, then you can use a simple lifecycle method like componentWillReceiveProps there you can read the new props and even compare the to the old props and act upon it, meaning that based on that you can then update your state. Let me know if this helps otherwise I can update my answer ;)

    EDIT:

    After reading your comment, this is what you want to do:

    ...
    componentWillReceiveProps(nextProps) {
      // In here you can also use this.props to compare the current props
      // to the new ones and do something about it
      this.setState({ myStateField: nextProps.propFromRedux });
    }
    ...