У меня есть 3 компонента.Нужно сделать так чтобы при клике на каждую из кнопок(Button.jsx) открывалась modal с разным текстом(modal одна и та же)

///Modal.jsx

import React, { Component } from "react";
import Portal from "./Portal";
import styled from "styled-components";
import { ImCross } from "react-icons/im"


// styles

const ModalOverlay = styled.div`
  background-color: rgba(0, 0, 0, 0.5);
  position: fixed;
  top: 0;
  bottom: 0;
  left: 0;
  right: 0;
`

const ModalWindow = styled.div`
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  background-color: #FFF;
  min-height: 200px;
  width: 500px;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
`
const ModalHeader = styled.div`
    padding: 10px 20px;
    min-height: 60px;
    border-bottom: 1px solid rgba(0, 0, 0, 0.2);
    display: flex;
    justify-content: space-between;
    box-sizing: border-box;
    align-items: center;
` 

const ModalBody = styled.div`
    padding: 10px 20px;
`
const ModalTitle = styled.div`
    font-weight: bold;
`
const ModalFooter = styled.div`
    padding: 10px 20px;
    display: flex;
    justify-content: flex-end;
    align-items: center;
`
 
//class component

class Modal extends Component {
  render() {
    return(
     <>
       { this.props.isOpen && 
          <Portal> 
            <ModalOverlay>
              <ModalWindow onClick={e => e.stopPropagation()}>
                <ModalHeader>
                  <ModalTitle>{this.props.header}</ModalTitle>
                  <ImCross 
                      style={{cursor: "pointer"}} 
                      onClick={this.props.closeButton}
                  />
                </ModalHeader>
                <ModalBody>
                  {this.props.children}
                </ModalBody>
                <ModalFooter>
                  <button 
                    style={{marginRight: '15px', cursor: 'pointer'}} 
                    onClick={this.props.onCancel} invert='true'>
                      Cancel
                  </button>
                  <button 
                    style={{cursor: 'pointer'}} 
                    onClick={this.props.onSubmit}>
                       Submit
                  </button>
                </ModalFooter>
              </ModalWindow>
            </ModalOverlay>
          </Portal>
      } 
     </>
    )
  }
}

export default Modal;



///App.jsx

import React, { Component } from "react";
import Button from './components/Button';
import Modal from './components/Modal';
import GlobalStyle from './globalStyles';



class App extends Component {
  state = {isOpen: false}

  clickedOnCross = () => {
    this.setState({ isOpen: false})
  }

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

  handleSubmit = () => {
    console.log('Submited!');
    this.setState({ isOpen: false });
  }

  handleCancel = () => {
    console.log('Canceled!');
    this.setState({ isOpen: false });
  }

  render(){
    return(
        <div className='App'>
          <GlobalStyle/>
          <Button 
            onClick={this.openModal}
            backgroundColor='   rgb(0,0,255, 0.8)' 
            text='button_1'
          />
          <Button 
            onClick={this.openModal}
            backgroundColor='rgb(255,255,0)'
            text='button_2'
          />
          <Modal
              closeButton={this.clickedOnCross}
              header="Done on React Dialog window"
              isOpen={this.state.isOpen}
              onCancel={this.handleCancel}
              onSubmit={this.handleSubmit}
          >
            Opened modal
          </Modal>
       </div>
    )
  }
}

export default App;


///Button.jsx

import React, { Component } from "react";
import styled from "styled-components";

//styles

const LinkContainer = styled.div`
  display: flex;
  align-items: center;
  justify-content: center;
  height: 100vh;
`

const Link = styled.a`
  cursor: pointer;
  text-decoration: none;
  display: inline-block;
  color: #fff;
  padding: 20px 30px;
  margin: 10px 20px;
  border-radius: 10px;
  font-family: 'Montserrat', sans-serif;
  text-transform: uppercase;
  letter-spacing: 2px;
  background-size: 200% auto;
  box-shadow: 0 0 20px rgba(0, 0, 0, 0.1);
`

//class

class Button extends Component {
  render(){
    return(
      <LinkContainer>
        <Link 
          onClick={this.props.onClick}
          style={{backgroundColor: `${this.props.backgroundColor}`}}>
            {this.props.text}  
        </Link>
      </LinkContainer>
    )
  }
}

export default Button;

Ответы (1 шт):

Автор решения: Михаил В

Ну самое простое - расширьте Ваш стейт

 state = {isOpen: false, text: ''}

расширьте функцию openModal

 openModal = (newText) => {
    this.setState({ isOpen: !this.state.isOpen, text: newText});
  }

и в jsx выводите нужный текст

<Modal
              closeButton={this.clickedOnCross}
              header="Done on React Dialog window"
              isOpen={this.state.isOpen}
              onCancel={this.handleCancel}
              onSubmit={this.handleSubmit}
          >
            {this.state.text}
          </Modal>

скорректируйте код кнопок, чтоб получилось такое

<Button 
            onClick={() => this.openModal("my custom text")}
            backgroundColor='rgb(255,255,0)'
            text='button_2'
          />

где вместо my custom text текст конкретной кнопки

в остальных функциях можно на всякий случай очищать text

clickedOnCross = () => {
    this.setState({ isOpen: false, text: '' })
  }

handleSubmit = () => {
    console.log('Submited!');
    this.setState({ isOpen: false, text: '' });
  }

  handleCancel = () => {
    console.log('Canceled!');
    this.setState({ isOpen: false, text: '' });
  }
→ Ссылка