1

My app.js creates a widget layout, within it I have an handleWidgetSelection function which should take an id when an item is clicked in my modal component. When I console log in the handleWidgetSelection function I notice that the state is not updated and it remains null as I originally set it as. I am fairly new to react so any help would be great.

This is my app.js

class App extends Component {
constructor(props) {
    super(props);
    this.state={
    selectedWidgetId: null, //initially set as null because no widget is selected
    widgetOptions:[{name:"Data Table", comp:<DataTable/>},{name:"List", comp:<CheckboxList/>}],

    widgets:[ //array for layout 
        {id:1, content: <DataTable/>},
        {id:2, content: <CheckboxList/>},
        {id:3, content: ""},
        {id:4, content: ""}
    ],
     isModalOpen: false
    }

}
handleWidgetSelection=(id) => {

    this.setState({selectedWidgetId: id})
    console.log(this.state.selectedWidgetId); //trying to fix so this value does not always print null
}
.....

render() {
    const { classes } = this.props;

    return (

    <div className={classes.root}>
    //I am passing my values to the AddWidgetDialog component here

    <AddWidgetDialog handleWidgetSelection={this.handleWidgetSelection} widgets={this.state.widgetOptions} isModalOpen={this.state.isModalOpen} onRequestClose={this.onRequestClose} />
    <Grid container spacing={24}>
        {
            this.state.widgets.map((widget,index)=>{
                return(
                    <Grid item xs={12} sm={6}>
                        <Paper className={classes.paper}><Swappable id={widget.id} content={widget.content} delete={this.deleteEvent.bind(this,index)} add={this.addEvent.bind(this,index)}/></Paper>
                        </Grid>
                )
            })
        }
    </Grid>
    </div>
    );
}

This is my AddWidgetDialog component

import React, { PropTypes } from 'react';
import Modal from 'react-modal';

const AddWidgetDialog = ({ handleWidgetSelection, widgets, isModalOpen, onRequestClose}) => {
  const widgetItems = widgets.map((widget) => {
    return (
      <div className="list-group">
      <a href="#" onClick={() => handleWidgetSelection(widget.name)} className="list-group-item">
          <h6 className="list-group-item-heading">{widget.name}</h6>
        </a>
      </div>
    );
  });
  return (
    <Modal
      className="Modal__Bootstrap modal-dialog"
      isOpen={isModalOpen}>
      <div className="modal-content">
       <div className="modal-header">
         <button type="button" className="close" onClick={onRequestClose}>
           <span aria-hidden="true">&times;</span>
           <span className="sr-only">Close</span>
         </button>
         <h4 className="modal-title">Add a widget</h4>
       </div>
       <div className="modal-body">
         <h5>Pick a widget to add</h5>
         {widgetItems}
       </div>
       <div className="modal-footer">
         <button type="button" className="btn btn-default" onClick={onRequestClose}>Close</button>
       </div>
      </div>
    </Modal>
  );
};

export default AddWidgetDialog;
  • 1
    setState is async that why, do console.log in render you will get the updated state value, check [this answer](https://stackoverflow.com/questions/42593202/why-calling-setstate-method-doesnt-mutate-the-state-immediately/42593250#42593250) for more details. – Mayank Shukla Apr 03 '19 at 15:34

1 Answers1

0

setState maybe asynchronous. See the docs Why is setState giving me the wrong value?

handleWidgetSelection=(id) => {
    this.setState({selectedWidgetId: id})
    console.log(this.state.selectedWidgetId); //no guarantee state is updated or not.
}

You should use console.log() in the callback as second argument to the setState

handleWidgetSelection=(id) => {
    this.setState({selectedWidgetId: id},() => {
        console.log(this.state.selectedWidgetId); //state is updated now.
    })
}
Maheer Ali
  • 35,834
  • 5
  • 42
  • 73