简体   繁体   中英

Control modal from parent - React hooks | Reactstrap

I have a problem with controlling reactstrap Modal from the parent. I have basic knowledge of passing data to a child element, but I don't know how when it is more complex, like this... I'm in depression because I can't get it working for a whole day, sorry for bad English.

This is part of the code that is in the parent hook, this should on click show Modal (change state of child modal):

  import SignUp from "components/modals/ModalSignup";

  <NavLink href="#pablo" onClick={(e) => e.preventDefault()}>
      <SignUp/>
      <i className="ni ni-spaceship padding-right"></i>
      Register
  </NavLink>

How I should control the state of the Modal element from the parent element? eg When someone presses the register button it changes the state of the children hook (Modal)

Bellow is a working child hook where is reactstrap Modal element

import React from "react";

// reactstrap components
import {
  Button,
  Card,
  CardHeader,
  CardBody,
  FormGroup,
  Form,
  Input,
  InputGroupAddon,
  InputGroupText,
  InputGroup,
  Modal,
} from "reactstrap";

// Core Components

function ModalSignup() {
  const [modalOpen, setModalOpen] = React.useState(false);
  const [emailFocus, setEmailFocus] = React.useState("");
  const [passwordFocus, setPasswordFocus] = React.useState("");
  const [passwordConfirmFocus, setPasswordConfirmFocus] = React.useState("");
  return (
      <Modal
        isOpen={modalOpen}
        toggle={() => setModalOpen(!modalOpen)}
        className="modal-dialog-centered modal-sm"
      >
        <div className="modal-body p-0">
          <Card className="bg-secondary shadow border-0 mb-0">
            <CardHeader className="bg-white pb-5">
              <div className="text-muted text-center mb-3">
                <small>Sign Up with</small>
              </div>
              <div className="btn-wrapper text-center">
                <Button
                  className="btn-neutral btn-icon"
                  color="default"
                  href="#pablo"
                  onClick={(e) => e.preventDefault()}
                >
                  <span className="btn-inner--icon">
                    <img
                      alt="..."
                      src={require("assets/img/icons/common/google.svg")}
                    ></img>
                  </span>{" "}
                  <span className="btn-inner--text">Google</span>
                </Button>{" "}
                <Button
                  className="btn-neutral btn-icon"
                  color="default"
                  href="#pablo"
                  onClick={(e) => e.preventDefault()}
                >
                  <span className="btn-inner--icon">
                    <img
                      alt="..."
                      src={require("assets/img/icons/common/github.svg")}
                    ></img>
                  </span>{" "}
                  <span className="btn-inner--text">Github</span>
                </Button>
              </div>
            </CardHeader>
            <CardBody className="px-lg-5 py-lg-5">
              <div className="text-center text-muted mb-4">
                <small>Or sign up here:</small>
              </div>
              <Form role="form">
                <FormGroup className={"mb-3 " + emailFocus}>
                  <InputGroup className="input-group-alternative">
                    <InputGroupAddon addonType="prepend">
                      <InputGroupText>
                        <i className="ni ni-email-83"></i>
                      </InputGroupText>
                    </InputGroupAddon>
                    <Input
                      placeholder="Email"
                      type="email"
                      onFocus={() => setEmailFocus("focused")}
                      onBlur={() => setEmailFocus("")}
                    ></Input>
                  </InputGroup>
                </FormGroup>
                <FormGroup className={passwordFocus}>
                  <InputGroup className="input-group-alternative">
                    <InputGroupAddon addonType="prepend">
                      <InputGroupText>
                        <i className="ni ni-lock-circle-open"></i>
                      </InputGroupText>
                    </InputGroupAddon>
                    <Input
                      placeholder="Password"
                      type="password"
                      onFocus={() => setPasswordFocus("focused")}
                      onBlur={() => setPasswordFocus("")}
                    ></Input>
                  </InputGroup>
                </FormGroup>
                <FormGroup className={passwordConfirmFocus}>
                  <InputGroup className="input-group-alternative">
                    <InputGroupAddon addonType="prepend">
                      <InputGroupText>
                        <i className="ni ni-lock-circle-open"></i>
                      </InputGroupText>
                    </InputGroupAddon>
                    <Input
                      placeholder="Confirm Password"
                      type="password"
                      onFocus={() => setPasswordConfirmFocus("focused")}
                      onBlur={() => setPasswordConfirmFocus("")}
                    ></Input>
                  </InputGroup>
                </FormGroup>
                <div className="text-center">
                  <Button className="my-4" color="primary" type="button">
                    Sign Up
                  </Button>
                </div>
              </Form>
            </CardBody>
          </Card>
        </div>
      </Modal>
  );
}

export default ModalSignup;

Don't fall into depression. Try writing your SignUp modal this way:

import React, {Fragment} from 'react';

// reactstrap components
import {
  Button,
  Card,
  CardHeader,
  CardBody,
  FormGroup,
  Form,
  Input,
  InputGroupAddon,
  InputGroupText,
  InputGroup,
  Modal,
  NavLink //NavLink import
} from "reactstrap";

// Core Components

function ModalSignup() {
  const [modalOpen, setModalOpen] = React.useState(false);
  const [emailFocus, setEmailFocus] = React.useState("");
  const [passwordFocus, setPasswordFocus] = React.useState("");
  const [passwordConfirmFocus, setPasswordConfirmFocus] = React.useState("");

  const toggle = () => setModalOpen(!modalOpen);

  return (
     <Fragment>

       <NavLink href="#pablo" onClick={toggle}>
         <i className="ni ni-spaceship padding-right"></i>
         Register
       </NavLink>

      <Modal
        isOpen={modalOpen}
        toggle={toggle}
        className="modal-dialog-centered modal-sm"
      >
        <div className="modal-body p-0">
          <Card className="bg-secondary shadow border-0 mb-0">
            <CardHeader className="bg-white pb-5">
              <div className="text-muted text-center mb-3">
                <small>Sign Up with</small>
              </div>
              <div className="btn-wrapper text-center">
                <Button
                  className="btn-neutral btn-icon"
                  color="default"
                  href="#pablo"
                  onClick={(e) => e.preventDefault()}
                >
                  <span className="btn-inner--icon">
                    <img
                      alt="..."
                      src={require("assets/img/icons/common/google.svg")}
                    ></img>
                  </span>{" "}
                  <span className="btn-inner--text">Google</span>
                </Button>{" "}
                <Button
                  className="btn-neutral btn-icon"
                  color="default"
                  href="#pablo"
                  onClick={(e) => e.preventDefault()}
                >
                  <span className="btn-inner--icon">
                    <img
                      alt="..."
                      src={require("assets/img/icons/common/github.svg")}
                    ></img>
                  </span>{" "}
                  <span className="btn-inner--text">Github</span>
                </Button>
              </div>
            </CardHeader>
            <CardBody className="px-lg-5 py-lg-5">
              <div className="text-center text-muted mb-4">
                <small>Or sign up here:</small>
              </div>
              <Form role="form">
                <FormGroup className={"mb-3 " + emailFocus}>
                  <InputGroup className="input-group-alternative">
                    <InputGroupAddon addonType="prepend">
                      <InputGroupText>
                        <i className="ni ni-email-83"></i>
                      </InputGroupText>
                    </InputGroupAddon>
                    <Input
                      placeholder="Email"
                      type="email"
                      onFocus={() => setEmailFocus("focused")}
                      onBlur={() => setEmailFocus("")}
                    ></Input>
                  </InputGroup>
                </FormGroup>
                <FormGroup className={passwordFocus}>
                  <InputGroup className="input-group-alternative">
                    <InputGroupAddon addonType="prepend">
                      <InputGroupText>
                        <i className="ni ni-lock-circle-open"></i>
                      </InputGroupText>
                    </InputGroupAddon>
                    <Input
                      placeholder="Password"
                      type="password"
                      onFocus={() => setPasswordFocus("focused")}
                      onBlur={() => setPasswordFocus("")}
                    ></Input>
                  </InputGroup>
                </FormGroup>
                <FormGroup className={passwordConfirmFocus}>
                  <InputGroup className="input-group-alternative">
                    <InputGroupAddon addonType="prepend">
                      <InputGroupText>
                        <i className="ni ni-lock-circle-open"></i>
                      </InputGroupText>
                    </InputGroupAddon>
                    <Input
                      placeholder="Confirm Password"
                      type="password"
                      onFocus={() => setPasswordConfirmFocus("focused")}
                      onBlur={() => setPasswordConfirmFocus("")}
                    ></Input>
                  </InputGroup>
                </FormGroup>
                <div className="text-center">
                  <Button className="my-4" color="primary" type="button">
                    Sign Up
                  </Button>
                </div>
              </Form>
            </CardBody>
          </Card>
        </div>
      </Modal>
      </Fragment>
  );
}

export default ModalSignup;

Then, just render your modal SignUp like this <ModalSignup /> and it will show your register link without rendering the Modal first. Once clicked, the modal will appear.

I have not tested this, but this should work.

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