我目前有一个带有密闭系统的模态系统。有一个ModalWrapper处理关闭模态和表单提交。实际的模式内容包含在另一个组件中,我将其称为EventsModalForm:

模态包装:

import React, { useState } from 'react';
import PropTypes from 'prop-types';
import { EVENT_FORM_MODAL } from '../layout/modalTypes';

const ModalWrapper = props => {
  const handleBackgroundClick = e => {
    if (e.target === e.currentTarget) props.hideModal();
  };

  const onOk = () => {
    if (props.modal.currentModal === EVENT_FORM_MODAL){
      //Do form submition
    } else {
      props.onOk();
    }
    props.hideModal();
  };

  const [formStates, setFormStates] = useState({
    ...props.modal.form_fields
  });
  const handleFormChange = e => {
    return setFormStates({ ...formStates, [e.target.name]: [e.target.value] })
  }


  const okButton = props.showOk
    ? (
      <button
        className="btn btn-primary"
        onClick={onOk}
        disabled={props.okDisabled}
      >
        {props.modal.okText}
      </button>
    ) : null;


  return (
    <div className="modal-overlay-div" onClick={handleBackgroundClick}>
      <div style={modal_content_div}>
        <header>
            <span>
              <button onClick={props.hideModal} className="close">&times;</button>
            </span>
            <h1>{props.title}</h1>
          <hr />
        </header>

        {props.children}

        {okButton}
      </div>
    </div>
  );
};
//content shortened for clarity

export default ModalWrapper;


EventsModalForm:

import React from 'react';
import {
  Button,
  Form,
  FormGroup,
  Input,
  Label
} from "reactstrap";

import 'flatpickr/dist/themes/material_blue.css';
import Flatpickr from 'react-flatpickr';


import ModalWrapper from './ModalWrapper';

const EventsFormModal = props => {
  //have form hook here
  return (
    <ModalWrapper
      {...props}
      title="Event form"
      width={600}
      showOk={true}
    >
      <Form>
        //form...
      </Form>
    </ModalWrapper>
  );
};

export default EventsFormModal;


我试图在EventsFormModal中使用钩子,并且每当调用onOk时,都将状态传递给ModalWrapper。但是,通过设置我的模态的方法,我似乎找不到找到将状态提升到ModalWrapper的方法。传递给ModalWrapper和EventsFormModal的道具是相同的,所以我将无法在父组件中创建一个函数并将其作为道具传递给子代。任何帮助,将不胜感激!

最佳答案

我假设您想在用户单击“确定”后将输入的数据传递回ModalWrapper。我做了这个小演示,以演示如何执行此操作。



const { useState } = React;
const { render } = ReactDOM;

const SomeModal = () => {
  const [show, setShow] = useState(false);
  const [name, setName] = useState("");
  const [email, setEmail] = useState("");

  const showModal = () => setShow(true);
  const hideModal = () => setShow(false);

  const handleNameChange = event => setName(event.target.value);
  const handleEmailChange = event => setEmail(event.target.value);

  return (
    <main>
      <ModalWrapper show={show} handleClose={hideModal} onOk={({name, email})}>
        <input type="text" onChange={handleNameChange} placeholder="Name" />
        <input type="text" onChange={handleEmailChange} placeholder="Email" />
      </ModalWrapper>
      <button type="button" onClick={showModal}>
        Open Modal
      </button>
    </main>
  );
};

const ModalWrapper = ({ handleClose, show, children, onOk }) => {
  const [onOkData, setOnOkData] = useState();
  const showHideClassName = show ? "modal display-block" : "modal display-none";

  const handleModalClose = (event, data) => {
    handleClose();
    setOnOkData(onOk);
  }

  return (
    <div>
    <div className={showHideClassName}>
      <section className="modal-main">
        {children}
        <button onClick={handleModalClose}>Ok</button>
      </section>
    </div>
      {onOkData
        ? <pre>This data was sent from "SomeModal": {JSON.stringify(onOkData, null, 2)}</pre>
        : ""}
    </div>
  );
};

const App = () => <SomeModal />

render(<App />, document.body);

.modal {
  position: fixed;
  top: 0;
  left: 0;
  width:100%;
  height: 100%;
  background: rgba(0, 0, 0, 0.6);
}

.modal-main {
  position:fixed;
  background: white;
  width: 80%;
  height: auto;
  top:50%;
  left:50%;
  padding: 20px;
  transform: translate(-50%,-50%);
}

.display-block {
  display: block;
}

.display-none {
  display: none;
}

<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.12.0/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.11.0/umd/react-dom.production.min.js"></script>

09-16 13:29