user11850868
user11850868

Reputation:

setState function in reactjs is not setting state. How to overcome this problem?

To open a bootstrap modal I'm setting state {isOpen: true} but setState doesn't update the state

I've used async/await , setTimeout but nothing works.Same modal is opening in my another component.

import React from 'react';
import Dialog from 'react-bootstrap-dialog'
import { Button } from 'react-bootstrap'
import { Modal } from 'react-bootstrap'

class EventComponent extends React.Component {
    constructor(props) {
      super(props);
     this.state = {
      isOpen: false
    };
    this.onClickdialog = this.onClickdialog.bind(this);
    this.toggleModal = this.toggleModal.bind(this);
  }

  toggleModal = () => {
    console.log('open', this.state.isOpen)
    this.setState({ isOpen: !this.state.isOpen }, console.log('open', 
    this.state.isOpen));
  }

  onClickdialog() {
    debugger
    this.toggleModal();
    // this.dialog.show('Hello Dialog!')
  }
  renderEvent(event) {
    const eventType = event.EventType;
    const name = event.Name;
    const isApproved = event.IsApproved === 1 ? 'approved' : 'unapproved';
    switch (eventType) {
      case 'Birthday': return (<div className='birthday' title={eventType}>
        <i className="fas fa-birthday-cake" ></i>&nbsp;{name}
      </div>);
      case 'Full Day': return (<div className={`fullday ${isApproved}`} title= 
       {eventType}>
        <i className="fas fa-umbrella-beach"></i>&nbsp;{name}&nbsp;
       <i style={{ marginTop: '-2px', position: 'absolute' }} >
          <a onClick={this.onClickdialog.bind(this)} style={{ fontWeight: 
       'bold' }}>...</a></i>
      </div>);
      default: return (<div>{eventType}:&nbsp;{name}</div>);
    }
  }
  render() {
    return (
      <div>
        {this.renderEvent(this.props.event)}
        <Modal className={"override-fade"} show={this.state.isOpen}
          onClose={this.toggleModal}>
        </Modal>
      </div>
    )
   }
  }
  export default EventComponent;

Expecting isOpen state to change on updating state on click

Upvotes: 0

Views: 509

Answers (6)

Herat Patel
Herat Patel

Reputation: 798

You can use previous state in setState api.

toggleModal = () => {
    this.setState((state) => ({
        isOpen: !state.isOpen
    }))
}

here, state represents previous state.

and also please can you remove extra bind from the onClick event.

<a onClick={this.onClickdialog} style={{ fontWeight: 'bold' }}>...</a>

Upvotes: 1

Akram Badah
Akram Badah

Reputation: 427

Your code actually works try adding something in your Modal like this:

return (
   <div>
     {this.renderEvent(this.props.event)}
     <Modal className={"override-fade"} show={this.state.isOpen}
      onClose={this.toggleModal}>
       <h1>test</h1>
     </Modal>
   </div>
)

and then give it a try. Also I believe that you didn't import bootsrap's css file you should import it.

Upvotes: 0

Smit Vora
Smit Vora

Reputation: 470

check below function,

toggleModal = () => {
    const { isOpen } = this.state;
    console.log('before ', isOpen);
    this.setState((prevState) => {
      // prevState before updating state
      console.log('before changing state', prevState.isOpen);
      return {
        isOpen: !prevState.isOpen,
      };
    }, () => {
      // callback after setting state
      const { isOpen: afterIsOpen } = this.state;
      console.log('after update ', afterIsOpen);
    });
  }

Upvotes: 0

Dixit Savaliya
Dixit Savaliya

Reputation: 413

Try This,

toggleModal = () => {
     console.log('open', this.state.isOpen)
     this.setState({ isOpen: !this.state.isOpen });
     console.log(this.state.isopen);}

Upvotes: 0

J. Ryd
J. Ryd

Reputation: 44

Just as Yanis said, you´re logging it wrong. Second argument of setState needs to be a callback function, however you´re calling console.log right away. Instead do:

this.setState({ isOpen: !this.state.isOpen }, () => console.log(...))

btw, you don´t have to bind class properties that is defined using arrow functions

Upvotes: 1

Yanis
Yanis

Reputation: 4997

I think you might probably check it wrong way. Does this console.log works for you?

this.setState({ isOpen: !this.state.isOpen }, console.log('open', 
    this.state.isOpen))

I think instead you should try something like

this.setState(
  { isOpen: !this.state.isOpen },
  () => {
    console.log('open', this.state.isOpen))
  }

Upvotes: 0

Related Questions