Home > Mobile >  react-bootstrap modal not reacting to property change
react-bootstrap modal not reacting to property change

Time:07-05

I am using React v18.1, react-bootstrap v2.4. I have a Modal component I am trying to get to display upon a button press. The modal component is quite simple:

class AdjustmentModal extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            'show': this.props.show
        };

        this.handleClose = this.handleClose.bind(this);
    }

    handleClose() {
        this.setState({ show: false })
    }

    render() {
        return (
            <Modal show={this.state.show} onHide={this.handleClose}>
                [ ... Modal Content Here ... ]
            </Modal>
        );
    }
}

export default AdjustmentModal;

As you can see, I bind the modal's show property to the value of show in state.

Then, in the component in which I want to display my modal, I have the following:

// Within render() ...
<AdjustmentModal 
    show={this.state.showAdjustment}
    partNo={this.state.partNo}
    onHandQty={this.state.onHandQty}
/>
// Futher on in the code, display the modal on click:
<Button className="icon" onClick={this.handleDisplayAdjustment}>
    <i className="bi bi-pencil-square"></i>
</Button>

handleDisplayAdjustment :

handleDisplayAdjustment(event) {
    event.preventDefault();
    this.setState({
        showAdjustment : true
    });
}

Now, despite the value showAdjustment in the parent component changing to true, the modal doesn't display.

I could set the <Modal show={this.props.show} .../> instead, but props are read-only, so there is no way to close the modal again if reading from props rather than state.

CodePudding user response:

You can use props, which is a better way to handle this if you want to close it then pass a method from the parent which when called update the state in the parent to false and due state update the parent component will re render and though the child component that is the modal component and the Modal will get the updated value which will be false. below is the code on how you can achieve that.

closeModal() {
  this.setState({
  showAdjustment: false
})
}

// Within render() ...
<AdjustmentModal 
    show={this.state.showAdjustment}
    partNo={this.state.partNo}
    onHandQty={this.state.onHandQty}
    onClose={this.closeModal.bind(this)}
/>
// Futher on in the code, display the modal on click:
<Button className="icon" onClick={this.handleDisplayAdjustment}>
    <i className="bi bi-pencil-square"></i>
</Button>

For the child component

    class AdjustmentModal extends React.Component {

    handleClose() {
        this.props.onClose()
    }

    render() {
        return (
            <Modal show={this.props.show} onHide={this.handleClose}>
                [ ... Modal Content Here ... ]
            </Modal>
        );
    }
}

export default AdjustmentModal;

EDIT: Explaining the approach This will make your Modal component a Controlled component that is controlled by Parent, also updating props as a state inside the child component is not the right way, which may create potential bugs.

  • Related