简体   繁体   中英

How to Toggle a modal in react and pass a child prop?

In this simple modal I just want to toggle a message. I have it almost but I am missing how to pass the child prop message, and the show button is closing the modal not the close button. Can some please explain the solution and the contextual details?

Here is my code and a Link to code sandbox App.js

import React, { Component } from "react";
import ReactDOM from "react-dom";
import Modal from "./Component/Modal";

import "./styles.css";
export default class App extends Component {
  constructor(props) {
    super();
    this.state = {
      show: false
    };
  }
  showModal = e => {
    this.setState({
      show: true
    });
    this.setState({
      show: !this.state.show
    });
  };
  render() {
    return (
      <div className="App">
        <Modal onClose={this.showModal} show={this.state.show} />
        <button
          onClick={e => {
            this.showModal();
          }}
        >
          Show
        </button>
      </div>
    );
  }
}
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);

Modal.js

import React from "react";
export default class Modal extends React.Component {
  constructor(props) {
    super();
    this.state = {};
  }
  onClose = e => {
    this.props.show = false;
    this.props.onClose && this.props.onClose(e);
  };
  render() {
    if (!this.props.show) {
      return null;
    }
    return (
      <div>
        {this.props.children} in Modal
        <button
          onClick={e => {
            this.onClose(e);
          }}
        >
          Close
        </button>
      </div>
    );
  }
}

I tried to follow the first answer for the App.js like this but it didnt work and I thought I already tried the second thing mentioned in the answer, and that was why I had two just testing something I knew was wrong.

import React, { Component } from "react";
import ReactDOM from "react-dom";
import Modal from "./Component/Modal";

import "./styles.css";
export default class App extends Component {
  constructor(props) {
    super();
    this.state = {
      show: false
    };
  }
  showModal = (show) => {
    this.setState({
      show: show
    });
  };
  render() {
    return (
      <div className="App">
        <Modal onClose={e => this.showModal(false)} show={this.state.show} />
        <button
          onClick={e => {
            this.showModal();
          }}
        >
          Show
        </button>
      </div>
    );
  }
}
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);

Your answer will fill in the blanks to this bits and pieces article

I made to toggle your show button and also if you want to close using close button that is also working. you can change as you want based on requirement.

App.js

export default class App extends Component {
  constructor() {
    super();
    this.state = {
      show: false
    };
  }
  showModal = () => {
    this.setState(prev=>({
      show: !prev.show
    }));
  };
  render() {
    return (
      <div className="App">
        <Modal onClose={this.showModal} show={this.state.show} />
        <button
          onClick={e => {
            this.showModal();
          }}
        >
          Show
        </button>
      </div>
    );
  }
}

Model/index.js

export default class Modal extends React.Component {
  render() {
    if (!this.props.show) {
      return null;
    }
    return (
      <div>
        {this.props.children} in Modal
        <button
          onClick={this.props.onClose}
        >
          Close
        </button>
      </div>
    );
  }
}

I guess, it is because setState is async and I am not sure, why you are calling it two times. Better pass an argument like this:

showModal = (show) => {
  this.setState({
    show: show
  });
};

And use it like this:

<Modal onClose={(e) => this.showModal(false)}

or just make it like this (without an argument):

showModal = () => {
  this.setState({
    show: !this.state.show
  });
};

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