我用于提交和编辑表单的 React 模态组件不会关闭?
My React modal component for a submit and edit form won't close?
我有一个 React 项目,其中有一个模态组件。有一个打开模式的按钮可以正常工作,但另一个用于关闭模式的按钮不起作用。我试图删除 onClick 函数,但这没有任何区别。下面是代码:
import React, { useState, useContext, useEffect, Fragment } from "react";
import ContactContext from "../../context/contact/contactContext";
// CrUd - Create and Update contact
const ContactForm = () => {
const contactContext = useContext(ContactContext);
const { createContact, clearCurrentContact, updateContact, current } =
contactContext;
// add contact details of current contact if edit button is clicked
useEffect(() => {
current
? setContact(current)
: setContact({
name: "",
email: "",
phone: "",
type: "personal",
});
}, [contactContext, current]);
// default values of the contact form
const [contact, setContact] = useState({
name: "",
email: "",
phone: "",
type: "personal",
});
const { name, email, phone, type } = contact;
// add values to temporary object
const onChange = change =>
setContact({ ...contact, [change.target.name]: change.target.value });
// if submit button is clicked
const onSubmit = submit => {
submit.preventDefault();
// choose weather to create or update a contact
!current ? createContact(contact) : updateContact(contact);
// revert form to default values
clearContactForm();
};
// if clear button is clicked
const clearContactForm = () => {
if (current) clearCurrentContact();
};
return (
<Fragment>
<a href="#contact-form">
<button className="create-contact-button">+</button>
</a>
<form className="contact-form" id="contact-form" onSubmit={onSubmit}>
<h2>{current ? "Update contact" : "Create contact"}</h2>
{/* input fields */}
<input
className="input-field"
type="text"
name="name"
value={name}
onChange={onChange}
placeholder="Name"
required
/>
<input
className="input-field"
type="email"
name="email"
value={email}
onChange={onChange}
placeholder="Email"
/>
<input
className="input-field"
minLength="8"
maxLength="8"
type="phone"
name="phone"
value={phone}
onChange={onChange}
placeholder="Phone"
/>
{/* personal or professional check box */}
<div>
<h3>Contact type</h3>
<input
type="radio"
name="type"
value="personal"
checked={type === "personal"}
onChange={onChange}
/>
Personal
<input
type="radio"
name="type"
value="professional"
checked={type === "professional"}
onChange={onChange}
/>
Professional
</div>
{/* submit and clear button */}
<div>
<a href="#!">
<input
className="button button-submit"
type="submit"
value={current ? "Update contact" : "Create contact"}
/>
</a>
</div>
<div>
<a href="#!">
<button
className="button button-form-clear"
onClick={clearContactForm}
>
Cancel
</button>
</a>
</div>
</form>
</Fragment>
);
};
export default ContactForm;
:root {
--main-color: #00308f;
--secondary-color: #7cb9e8;
--dark-color: #444;
--light-color: #fafafa;
}
body {
font-family: Montserrat,sans-serif;
background-color: var(--light-color);
color: var(--dark-color);
text-align: justify;
margin: 70px 0 0;
padding: 1em;
}
h2,
h3 {
color: var(--main-color);
}
.button {
margin: 0 0.5em;
border-radius: 0.5em;
padding: 0.5em 1.25em;
font-weight: 700;
min-width: 80px;
}
.create-contact-button {
position: fixed;
bottom: 0.75em;
right: 0.75em;
display: grid;
align-items: center;
border: 0.1em solid var(--light-color);
border-radius: 50%;
padding: 0.5em 0.75em;
background-color: var(--main-color);
color: var(--light-color);
opacity: 90%;
z-index: 2;
font-weight: 700;
font-size: 3em;
box-shadow: 1px 1px 0.1em var(--dark-color);
}
.create-contact-button:hover {
background-color: var(--light-color);
color: var(--main-color);
border: 0.1em solid var(--main-color);
box-shadow: 1px 1px 0.5em var(--dark-color);
transition-duration: 0.4s;
}
.contact-form {
position: fixed;
left: 50%;
top: 50%;
transform: translate(-50%,-50%);
display: grid;
align-self: center;
width: 350px;
z-index: 1;
background-color: var(--secondary-color);
border: 2px solid var(--main-color);
border-radius: 1em;
padding: 1em;
visibility: hidden;
}
.contact-form:target {
visibility: visible;
}
.button-submit {
margin: 1.25em 0 0;
padding: 0.6em 1.25em;
width: 100%;
background-image: linear-gradient(-45deg,var(--main-color),var(--secondary-color),var(--secondary-color),var(--secondary-color),var(--main-color));
border: solid 1.5px var(--main-color);
color: var(--main-color);
}
.button-submit:hover {
background-image: linear-gradient(-45deg,var(--secondary-color),var(--main-color),var(--main-color),var(--main-color),var(--secondary-color));
border: solid 1.5px var(--secondary-color);
color: var(--light-color);
transition-duration: 0.4s;
}
.button-form-clear {
background-color: #d3d3d3;
border: solid 1.5px #a9a9a9;
color: var(--dark-color);
margin: 1.25em 0;
padding: 0.6em 1.25em;
width: 100%;
border: solid 1.5px var(--main-color);
}
.button-form-clear:hover {
background-color: #a9a9a9;
border: solid 1.5px #d3d3d3;
color: var(--light-color);
transition-duration: 0.4s;
}
.input-field {
margin: 0.5em 0;
border: solid 1px var(--secondary-color);
border-radius: 0.5em;
padding: 0 1em;
height: 40px;
box-sizing: border-box;
}
@media screen and (max-width:614px) {
body {
margin-top: 130px;
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
为什么模态没有关闭?
元素 button
、input
不得作为 a
元素的后代出现,请在此处查看 https://validator.w3.org/。您必须从 a
中删除 button
、input
,在这种情况下单击 a
不起作用。
Demo https://codesandbox.io/s/elegant-kalam-h3idc,所有使用ContactContext
的代码,都注释掉了。还在 form
上使用 useRef
,通过 dispatchEvent
进行提交
我有一个 React 项目,其中有一个模态组件。有一个打开模式的按钮可以正常工作,但另一个用于关闭模式的按钮不起作用。我试图删除 onClick 函数,但这没有任何区别。下面是代码:
import React, { useState, useContext, useEffect, Fragment } from "react";
import ContactContext from "../../context/contact/contactContext";
// CrUd - Create and Update contact
const ContactForm = () => {
const contactContext = useContext(ContactContext);
const { createContact, clearCurrentContact, updateContact, current } =
contactContext;
// add contact details of current contact if edit button is clicked
useEffect(() => {
current
? setContact(current)
: setContact({
name: "",
email: "",
phone: "",
type: "personal",
});
}, [contactContext, current]);
// default values of the contact form
const [contact, setContact] = useState({
name: "",
email: "",
phone: "",
type: "personal",
});
const { name, email, phone, type } = contact;
// add values to temporary object
const onChange = change =>
setContact({ ...contact, [change.target.name]: change.target.value });
// if submit button is clicked
const onSubmit = submit => {
submit.preventDefault();
// choose weather to create or update a contact
!current ? createContact(contact) : updateContact(contact);
// revert form to default values
clearContactForm();
};
// if clear button is clicked
const clearContactForm = () => {
if (current) clearCurrentContact();
};
return (
<Fragment>
<a href="#contact-form">
<button className="create-contact-button">+</button>
</a>
<form className="contact-form" id="contact-form" onSubmit={onSubmit}>
<h2>{current ? "Update contact" : "Create contact"}</h2>
{/* input fields */}
<input
className="input-field"
type="text"
name="name"
value={name}
onChange={onChange}
placeholder="Name"
required
/>
<input
className="input-field"
type="email"
name="email"
value={email}
onChange={onChange}
placeholder="Email"
/>
<input
className="input-field"
minLength="8"
maxLength="8"
type="phone"
name="phone"
value={phone}
onChange={onChange}
placeholder="Phone"
/>
{/* personal or professional check box */}
<div>
<h3>Contact type</h3>
<input
type="radio"
name="type"
value="personal"
checked={type === "personal"}
onChange={onChange}
/>
Personal
<input
type="radio"
name="type"
value="professional"
checked={type === "professional"}
onChange={onChange}
/>
Professional
</div>
{/* submit and clear button */}
<div>
<a href="#!">
<input
className="button button-submit"
type="submit"
value={current ? "Update contact" : "Create contact"}
/>
</a>
</div>
<div>
<a href="#!">
<button
className="button button-form-clear"
onClick={clearContactForm}
>
Cancel
</button>
</a>
</div>
</form>
</Fragment>
);
};
export default ContactForm;
:root {
--main-color: #00308f;
--secondary-color: #7cb9e8;
--dark-color: #444;
--light-color: #fafafa;
}
body {
font-family: Montserrat,sans-serif;
background-color: var(--light-color);
color: var(--dark-color);
text-align: justify;
margin: 70px 0 0;
padding: 1em;
}
h2,
h3 {
color: var(--main-color);
}
.button {
margin: 0 0.5em;
border-radius: 0.5em;
padding: 0.5em 1.25em;
font-weight: 700;
min-width: 80px;
}
.create-contact-button {
position: fixed;
bottom: 0.75em;
right: 0.75em;
display: grid;
align-items: center;
border: 0.1em solid var(--light-color);
border-radius: 50%;
padding: 0.5em 0.75em;
background-color: var(--main-color);
color: var(--light-color);
opacity: 90%;
z-index: 2;
font-weight: 700;
font-size: 3em;
box-shadow: 1px 1px 0.1em var(--dark-color);
}
.create-contact-button:hover {
background-color: var(--light-color);
color: var(--main-color);
border: 0.1em solid var(--main-color);
box-shadow: 1px 1px 0.5em var(--dark-color);
transition-duration: 0.4s;
}
.contact-form {
position: fixed;
left: 50%;
top: 50%;
transform: translate(-50%,-50%);
display: grid;
align-self: center;
width: 350px;
z-index: 1;
background-color: var(--secondary-color);
border: 2px solid var(--main-color);
border-radius: 1em;
padding: 1em;
visibility: hidden;
}
.contact-form:target {
visibility: visible;
}
.button-submit {
margin: 1.25em 0 0;
padding: 0.6em 1.25em;
width: 100%;
background-image: linear-gradient(-45deg,var(--main-color),var(--secondary-color),var(--secondary-color),var(--secondary-color),var(--main-color));
border: solid 1.5px var(--main-color);
color: var(--main-color);
}
.button-submit:hover {
background-image: linear-gradient(-45deg,var(--secondary-color),var(--main-color),var(--main-color),var(--main-color),var(--secondary-color));
border: solid 1.5px var(--secondary-color);
color: var(--light-color);
transition-duration: 0.4s;
}
.button-form-clear {
background-color: #d3d3d3;
border: solid 1.5px #a9a9a9;
color: var(--dark-color);
margin: 1.25em 0;
padding: 0.6em 1.25em;
width: 100%;
border: solid 1.5px var(--main-color);
}
.button-form-clear:hover {
background-color: #a9a9a9;
border: solid 1.5px #d3d3d3;
color: var(--light-color);
transition-duration: 0.4s;
}
.input-field {
margin: 0.5em 0;
border: solid 1px var(--secondary-color);
border-radius: 0.5em;
padding: 0 1em;
height: 40px;
box-sizing: border-box;
}
@media screen and (max-width:614px) {
body {
margin-top: 130px;
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
为什么模态没有关闭?
元素 button
、input
不得作为 a
元素的后代出现,请在此处查看 https://validator.w3.org/。您必须从 a
中删除 button
、input
,在这种情况下单击 a
不起作用。
Demo https://codesandbox.io/s/elegant-kalam-h3idc,所有使用ContactContext
的代码,都注释掉了。还在 form
上使用 useRef
,通过 dispatchEvent