简体   繁体   中英

setState not work in react-bootstrap modal

When i want to use setState, it will not work. for example close or open bootstrap modal.

Here is the my index.js contents:

import App from "./Modal";

ReactDOM.render(<App />, document.getElementById("root"));

And here is my Modal.js contents:

import React, { Component } from "react";
import socket from "socket.io-client";
import Modal from "react-bootstrap/Modal";

const Socket = socket.connect("ws://127.0.0.1:3004");

class Parent extends Component {
  constructor(props) {
    super(props);
    this.state = {
      show: false
    };
    this.onChange = this.onChange.bind(this);
  }
  onChange(event, type) {
    this.setState({ show: false });
  }
  render() {
    const { show } = this.state;
    return <Child onChange={this.onChange.bind(this, show)} />;
  }
}

class Child extends Component {
  _isMounted = false;
  constructor(props) {
    super(props);
    this.state = {
      show: false
    };
    this.handleShow = this.handleShow.bind(this);
    this.handleClose = this.handleClose.bind(this);
  }
  handleShow() {
    if (this._isMounted) {
      this.setState({ show: true });
      this.props.onChange(true, true);
    }
  }
  handleClose() {
    if (this._isMounted) {
      this.setState({ show: false });
      this.props.onChange(false, false);
    }
  }
  modal(response) {
    if (this._isMounted) {
      this.setState({ show: true });
      this.props.onChange(true, true);
    }
  }
  componentDidMount() {
    this._isMounted = true;
    Socket.on("message", data => this.modal(data));
  }
  render() {
    return (
      <>
        <Modal
          size="lg"
          show={this.handleShow}
          onHide={this.handleClose}
          aria-labelledby="st-lg-modal"
        >
          <Modal.Header closeButton>
            <Modal.Title id="st-lg-modal">Modal Name</Modal.Title>
          </Modal.Header>
          <Modal.Body>Contents</Modal.Body>
        </Modal>
      </>
    );
  }
}

export default Parent;

But setState is not work.

Take a look to my example: https://codesandbox.io/s/epic-herschel-344dl

Demo: https://344dl.csb.app/

Close button not work !

How can fix this ?

Some notice points:

  • React-bootstrap Modal props show is receiving boolean type value, rather than a callback function.
  • You don't need to write the handler functions inside your child if you want to reuse it. As well as there is no need for _isMounted .
  • Use public class field syntax (arrow function) instead of bind(this) can reduce your code and lead to better performance.

The modal now can be closed normally.

import React, { Component } from "react";
import socket from "socket.io-client";
import Modal from "react-bootstrap/Modal";

const Socket = socket.connect("ws://127.0.0.1:3004");

class Parent extends Component {
  constructor(props) {
    super(props);
    this.state = {
      show: true
    };
  }
  onChange = () => {
    this.setState(perv => { show: !prev.show });
  };
  render() {
    const { show } = this.state;
    return <Child onChange={this.onChange} show={show} />;
  }
}

class Child extends Component {
  constructor(props) {
    super(props);
    this.state = {};
  }
  componentDidMount() {
    Socket.on("message", data => this.modal(data));
  }
  render() {
    const { show, onChange } = this.props;
    return (
      <>
        <Modal
          size="lg"
          show={show}
          onHide={onChange}
          aria-labelledby="st-lg-modal"
        >
          <Modal.Header closeButton>
            <Modal.Title id="st-lg-modal">Modal Name</Modal.Title>
          </Modal.Header>
          <Modal.Body>Contents</Modal.Body>
        </Modal>
      </>
    );
  }
}

export default Parent;

编辑 love-hypatia-x26xx

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM