Formik 复选框导致检查延迟太多 #1901
Formik checkbox causing so much delay on checking #1901
每当我选中或取消选中 React Formik-Yup Checkbox 时都会造成如此多的延迟。
这是我的问题的代码框-
https://codesandbox.io/s/currying-cdn-76xys?fontsize=14
我为我的复选框组使用了两种方法,但 none 按预期工作。
一种是将 handleCheckBox 方法绑定到构造函数,另一种是直接使用 Formik 的 handleChange。
请帮我解决这个问题。
import React, { Component } from "react";
import { Formik, Form, Field, ErrorMessage } from "formik";
import * as Yup from "yup";
// form constants
const restaurantTypeOptions = ["Delivery", "Take away", "Dine in"];
const restaurantSuitedOptions = ["Family", "Couple", "Cafe"];
const debug = true;
class SignUp extends Component {
constructor(props) {
super(props);
this.state = {
restTypeArr: [],
restSuitArr: []
};
this.handleCheckBox = this.handleCheckBox.bind(this);
}
handleCheckBox(e) {
const newSelection = e.target.value;
let newSelectionArray;
if (Formik.values.restaurantType.indexOf(newSelection) > -1) {
newSelectionArray = Formik.values.restaurantType.filter(
s => s !== newSelection
);
} else {
newSelectionArray = [...Formik.values.restaurantType, newSelection];
}
this.setState(prevState => ({
restTypeArr: newSelectionArray
}));
}
render() {
return (
<div id="signupContainer" className="signinup-container">
<h3 className="mb-4"> Sign Up </h3>
<Formik
initialValues={{
//restaurantType: ['Delivery', 'Take away'],
restaurantType: this.state.restTypeArr,
restaurantSuited: []
}}
validationSchema={Yup.object().shape({
restaurantType: Yup.array().required("Please select at least one"),
restaurantSuited: Yup.array().required("Please select at least one")
})}
onSubmit={(values, { resetForm, setErrors, setSubmitting }) => {
setTimeout(() => {
console.log("Getting form values - ", values);
}, 500);
}}
enableReinitialize={true}
>
{props => {
const {
values,
touched,
errors,
isSubmitting,
handleChange,
handleBlur,
setFieldValue
} = props;
return (
<Form id="signUpForm" className="signinupForm" noValidate>
<div className="form-group">
<label className="form-label" htmlFor="restaurantType">
Restaurant Type
</label>
<div className="checkbox-group">
{restaurantTypeOptions.map((option, index) => {
return (
<label
key={option}
index={index}
className="checkbox-inline"
>
<Field
type="checkbox"
name="restaurantType"
value={option}
id={option}
checked={values.restaurantType.indexOf(option) > -1}
onChange={this.handleCheckBox}
/>
{option}
</label>
);
})}
</div>
<ErrorMessage
name="restaurantType"
component="span"
className="invalid-input"
/>
</div>
{/* Restaurant Type */}
<div className="form-group">
<label className="form-label" htmlFor="restaurantSuited">
Restaurant Suited for
</label>
<div className="checkbox-group">
{restaurantSuitedOptions.map(option => {
return (
<label key={option} className="checkbox-inline">
<Field
type="checkbox"
name="restaurantSuited"
value={option}
checked={
values.restaurantSuited.indexOf(option) > -1
}
//onChange={() => setFieldValue("restaurantSuited", option)}
onChange={() => {
if (values.restaurantSuited.includes(option)) {
values.restaurantSuited.pop(option);
} else {
values.restaurantSuited.push(option);
}
}}
/>
{option}
</label>
);
})}
</div>
<ErrorMessage
name="restaurantSuited"
component="span"
className="invalid-input"
/>
</div>
{/* Restaurant Suited */}
<button
type="submit"
className="btn btn-filled"
disabled={isSubmitting}
>
SignUp
</button>
{/*Submit */}
{debug && (
<>
<pre style={{ textAlign: "left" }}>
<strong>Values</strong>
<br />
{JSON.stringify(values, null, 2)}
</pre>
<pre style={{ textAlign: "left" }}>
<strong>Errors</strong>
<br />
{JSON.stringify(errors, null, 2)}
</pre>
</>
)}
</Form>
);
}}
</Formik>
</div>
);
}
}
export default SignUp;
我可能解释的不对,如果有人能指正我,请指正。
通过使用 checked
然后复选框将设置为该值,但无法更改 values.restaurantType.indexOf(option) > -1
该值将永远卡住,如果您打算设置默认值,请选中使用 defaultChecked
。
否则你将不得不使用 state with onChange
.
我可以看到你已经将 onChange 与 state 一起使用,但是 values.restaurantType.indexOf(option) > -1
的值是用 props 映射的,但是由于 props 是不可变的,所以该值永远不会改变
每当我选中或取消选中 React Formik-Yup Checkbox 时都会造成如此多的延迟。 这是我的问题的代码框- https://codesandbox.io/s/currying-cdn-76xys?fontsize=14
我为我的复选框组使用了两种方法,但 none 按预期工作。 一种是将 handleCheckBox 方法绑定到构造函数,另一种是直接使用 Formik 的 handleChange。
请帮我解决这个问题。
import React, { Component } from "react";
import { Formik, Form, Field, ErrorMessage } from "formik";
import * as Yup from "yup";
// form constants
const restaurantTypeOptions = ["Delivery", "Take away", "Dine in"];
const restaurantSuitedOptions = ["Family", "Couple", "Cafe"];
const debug = true;
class SignUp extends Component {
constructor(props) {
super(props);
this.state = {
restTypeArr: [],
restSuitArr: []
};
this.handleCheckBox = this.handleCheckBox.bind(this);
}
handleCheckBox(e) {
const newSelection = e.target.value;
let newSelectionArray;
if (Formik.values.restaurantType.indexOf(newSelection) > -1) {
newSelectionArray = Formik.values.restaurantType.filter(
s => s !== newSelection
);
} else {
newSelectionArray = [...Formik.values.restaurantType, newSelection];
}
this.setState(prevState => ({
restTypeArr: newSelectionArray
}));
}
render() {
return (
<div id="signupContainer" className="signinup-container">
<h3 className="mb-4"> Sign Up </h3>
<Formik
initialValues={{
//restaurantType: ['Delivery', 'Take away'],
restaurantType: this.state.restTypeArr,
restaurantSuited: []
}}
validationSchema={Yup.object().shape({
restaurantType: Yup.array().required("Please select at least one"),
restaurantSuited: Yup.array().required("Please select at least one")
})}
onSubmit={(values, { resetForm, setErrors, setSubmitting }) => {
setTimeout(() => {
console.log("Getting form values - ", values);
}, 500);
}}
enableReinitialize={true}
>
{props => {
const {
values,
touched,
errors,
isSubmitting,
handleChange,
handleBlur,
setFieldValue
} = props;
return (
<Form id="signUpForm" className="signinupForm" noValidate>
<div className="form-group">
<label className="form-label" htmlFor="restaurantType">
Restaurant Type
</label>
<div className="checkbox-group">
{restaurantTypeOptions.map((option, index) => {
return (
<label
key={option}
index={index}
className="checkbox-inline"
>
<Field
type="checkbox"
name="restaurantType"
value={option}
id={option}
checked={values.restaurantType.indexOf(option) > -1}
onChange={this.handleCheckBox}
/>
{option}
</label>
);
})}
</div>
<ErrorMessage
name="restaurantType"
component="span"
className="invalid-input"
/>
</div>
{/* Restaurant Type */}
<div className="form-group">
<label className="form-label" htmlFor="restaurantSuited">
Restaurant Suited for
</label>
<div className="checkbox-group">
{restaurantSuitedOptions.map(option => {
return (
<label key={option} className="checkbox-inline">
<Field
type="checkbox"
name="restaurantSuited"
value={option}
checked={
values.restaurantSuited.indexOf(option) > -1
}
//onChange={() => setFieldValue("restaurantSuited", option)}
onChange={() => {
if (values.restaurantSuited.includes(option)) {
values.restaurantSuited.pop(option);
} else {
values.restaurantSuited.push(option);
}
}}
/>
{option}
</label>
);
})}
</div>
<ErrorMessage
name="restaurantSuited"
component="span"
className="invalid-input"
/>
</div>
{/* Restaurant Suited */}
<button
type="submit"
className="btn btn-filled"
disabled={isSubmitting}
>
SignUp
</button>
{/*Submit */}
{debug && (
<>
<pre style={{ textAlign: "left" }}>
<strong>Values</strong>
<br />
{JSON.stringify(values, null, 2)}
</pre>
<pre style={{ textAlign: "left" }}>
<strong>Errors</strong>
<br />
{JSON.stringify(errors, null, 2)}
</pre>
</>
)}
</Form>
);
}}
</Formik>
</div>
);
}
}
export default SignUp;
我可能解释的不对,如果有人能指正我,请指正。
通过使用 checked
然后复选框将设置为该值,但无法更改 values.restaurantType.indexOf(option) > -1
该值将永远卡住,如果您打算设置默认值,请选中使用 defaultChecked
。
否则你将不得不使用 state with onChange
.
我可以看到你已经将 onChange 与 state 一起使用,但是 values.restaurantType.indexOf(option) > -1
的值是用 props 映射的,但是由于 props 是不可变的,所以该值永远不会改变