如何使用 handleSubmit 中的 Formik 承诺将反应状态更改为 show/hide a div?
How do I change react state using a promise with Formik inside handleSubmit to show/hide a div?
我需要你的帮助。
当使用 Formik 中的承诺提交表单时,我正在尝试使用 React 的状态在表单的发送按钮内创建一个 div show/hide 。我知道它与绑定 'this' 有关,但我不知道在哪里绑定它。我想这样做,以便在提交成功时显示垃圾复选标记。
我试过设置:
const that = this;
然后使用 'that' 和 checkSuccesBoxShowHandler 方法。但它在控制台中抛出了这个:
TypeError: Cannot read property 'checkSuccesBoxShowHandler' of undefined
代码如下:
class CForm extends React.Component {
state = {
checkSuccesBoxShow: false
}
checkSuccesBoxShowHandler = () => {
this.setState({
checkSuccesBoxShow: true
});
setTimeout(() => {
this.setState({
checkSuccesBoxShow: false
})
}, 3000);
}
render() {
const {
errors,
touched,
isSubmitting,
handleSubmit,
isValid,
bgColor
} = this.props;
const checkSuccessLottieOptions = {
loop: false,
autoplay: true,
animationData: checkSuccessLottie,
name: 'checkMarkSuccess',
rendererSettings: {
preserveAspectRatio: 'xMidYMid slice'
}
};
return (
<Form className={classes.contactForm} onSubmit={handleSubmit}>
<div className={classes.inputBox}>
<label className={touched.name && errors.name ? [classes.label, classes.labelError].join(' ') : classes.label} >Mi nombre es
<ErrorMessage name='name' component='p' className={classes.error} />
<Field type='text' name='name' placeholder='Tu nombre' autoComplete='name' className={bgColor ? [classes.inputElement, classes[bgColor]].join(' ') : classes.inputElement} />
</label>
</div>
<div className={classes.inputBox}>
<label className={touched.email && errors.email ? [classes.label, classes.labelError].join(' ') : classes.label} >Contáctame a
<ErrorMessage name='email' component='p' className={classes.error} />
<Field type='email' name='email' placeholder='tu@correo.com' autoComplete='email' className={bgColor ? [classes.inputElement, classes[bgColor]].join(' ') : classes.inputElement} />
</label>
</div>
<div className={classes.inputBox}>
<label className={touched.phone && errors.phone ? [classes.label, classes.labelError].join(' ') : classes.label} >Mi número de teléfono es
<ErrorMessage name='phone' component='p' className={classes.error} />
<Field type='phone' name='phone' placeholder='Tu número de teléfono' autoComplete='tel' className={bgColor ? [classes.inputElement, classes[bgColor]].join(' ') : classes.inputElement} />
</label>
</div>
<div className={classes.inputBox}>
<label className={touched.company && errors.company ? [classes.label, classes.labelError].join(' ') : classes.label} >Trabajo en
<ErrorMessage name='company' component='p' className={classes.error} />
<Field type='text' name='company' placeholder='Tu compañía' autoComplete='organization' className={bgColor ? [classes.inputElement, classes[bgColor]].join(' ') : classes.inputElement} />
</label>
</div>
<div className={classes.inputBox}>
<label className={touched.message && errors.message ? [classes.label, classes.labelError].join(' ') : classes.label} >Mensaje
<ErrorMessage name='message' component='p' className={classes.error} />
<Field component='textarea' name='message' placeholder='Empieza a escribir...' autoComplete='off' className={bgColor ? [classes.textAreaElement, classes[bgColor]].join(' ') : classes.textAreaElement} />
</label>
</div>
<button type='submit'
className={classes.sendBtn}
disabled={isSubmitting || !isValid}
>
<span style={isSubmitting ? { display: 'none' } : null}>Enviar</span>
<div className={isSubmitting ? [classes['sk-circle'], classes.showing].join(' ') : classes['sk-circle']}>
<div className={[classes['sk-circle1'], classes['sk-child']].join(' ')}></div>
<div className={[classes['sk-circle2'], classes['sk-child']].join(' ')}></div>
<div className={[classes['sk-circle3'], classes['sk-child']].join(' ')}></div>
<div className={[classes['sk-circle4'], classes['sk-child']].join(' ')}></div>
<div className={[classes['sk-circle5'], classes['sk-child']].join(' ')}></div>
<div className={[classes['sk-circle6'], classes['sk-child']].join(' ')}></div>
<div className={[classes['sk-circle7'], classes['sk-child']].join(' ')}></div>
<div className={[classes['sk-circle8'], classes['sk-child']].join(' ')}></div>
<div className={[classes['sk-circle9'], classes['sk-child']].join(' ')}></div>
<div className={[classes['sk-circle10'], classes['sk-child']].join(' ')}></div>
<div className={[classes['sk-circle11'], classes['sk-child']].join(' ')}></div>
<div className={[classes['sk-circle12'], classes['sk-child']].join(' ')}></div>
</div>
<div style={this.state.checkSuccesBoxShow
? { display: 'inline-block' }
: { display: 'none' }} >
<Lottie
options={checkSuccessLottieOptions}
height={50}
width={50}
/>
</div>
</button>
</Form>
);
}
};
const ContactForm = withFormik({
mapPropsToValues({ name, email, phone, company, message }) {
return {
name: name || '',
email: email || '',
phone: phone || '',
company: company || '',
message: message || ''
}
},
validationSchema: Yup.object().shape({
name: Yup.string().required('El nombre es requerido'),
email: Yup.string().email('Email invalido').required('Email requerido'),
phone: Yup.number().typeError('Debe ser un número telefónico'),
company: Yup.string(),
message: Yup.string().required('Mensaje requerido')
}),
handleSubmit(values, { resetForm, setSubmitting }) {
// This is the endpoint we created in our API Gateway. This is where we make our POST request, which calls our Lambda function.
const endpoint = '***********';
// We replace line to keep format of text in message value
const messageText = values.message;
const formattedMessageText = messageText.replace(/\n/g, '<br />');
let newValues = { ...values };
newValues.message = formattedMessageText;
// Here, we instantiate our Request. This is a special object used by the Fetch API so it knows where to send data, what data to send, and how to send it.
var lambdaRequest = new Request(endpoint, {
method: 'POST',
// Quick note: 'no-cors' mode is for development on localhost only!
mode: 'no-cors',
body: JSON.stringify(newValues)
});
const that = this;
// Call the Fetch API to make our request
fetch(lambdaRequest)
.then(response => {
console.log(response)
resetForm();
setSubmitting(false);
that.checkSuccesBoxShowHandler();
})
.catch(err => console.log(err));
}
})(CForm)
export default ContactForm
因为您在 withFormik
内部,这是一个 HOC(高阶组件),您无法访问组件状态,因此您需要另一种方法。
您可以使用由 this.props.form.status
传递给您的组件的 setStatus
。
所以当你想显示按钮时,你调用 setStatus
带有一些标志或值,在你的组件中你做一个条件,所以 show/hide 它。
你可以在this issue where this answer your problem中看到这个问题。
对于你的情况,你需要做类似
的事情
handleSubmit(values, { resetForm, setSubmitting, setStatus }) {
// Call the Fetch API to make our request
fetch(lambdaRequest)
.then(response => {
console.log(response)
resetForm();
setSubmitting(false);
setStatus(true); // setStatus to communicate with the component
that.checkSuccesBoxShowHandler();
})
.catch(err => console.log(err));
}
在你的组件中
{this.props.form.status && <Lottie
options={checkSuccessLottieOptions}
height={50}
width={50}
/>
}
我需要你的帮助。 当使用 Formik 中的承诺提交表单时,我正在尝试使用 React 的状态在表单的发送按钮内创建一个 div show/hide 。我知道它与绑定 'this' 有关,但我不知道在哪里绑定它。我想这样做,以便在提交成功时显示垃圾复选标记。
我试过设置:
const that = this;
然后使用 'that' 和 checkSuccesBoxShowHandler 方法。但它在控制台中抛出了这个:
TypeError: Cannot read property 'checkSuccesBoxShowHandler' of undefined
代码如下:
class CForm extends React.Component {
state = {
checkSuccesBoxShow: false
}
checkSuccesBoxShowHandler = () => {
this.setState({
checkSuccesBoxShow: true
});
setTimeout(() => {
this.setState({
checkSuccesBoxShow: false
})
}, 3000);
}
render() {
const {
errors,
touched,
isSubmitting,
handleSubmit,
isValid,
bgColor
} = this.props;
const checkSuccessLottieOptions = {
loop: false,
autoplay: true,
animationData: checkSuccessLottie,
name: 'checkMarkSuccess',
rendererSettings: {
preserveAspectRatio: 'xMidYMid slice'
}
};
return (
<Form className={classes.contactForm} onSubmit={handleSubmit}>
<div className={classes.inputBox}>
<label className={touched.name && errors.name ? [classes.label, classes.labelError].join(' ') : classes.label} >Mi nombre es
<ErrorMessage name='name' component='p' className={classes.error} />
<Field type='text' name='name' placeholder='Tu nombre' autoComplete='name' className={bgColor ? [classes.inputElement, classes[bgColor]].join(' ') : classes.inputElement} />
</label>
</div>
<div className={classes.inputBox}>
<label className={touched.email && errors.email ? [classes.label, classes.labelError].join(' ') : classes.label} >Contáctame a
<ErrorMessage name='email' component='p' className={classes.error} />
<Field type='email' name='email' placeholder='tu@correo.com' autoComplete='email' className={bgColor ? [classes.inputElement, classes[bgColor]].join(' ') : classes.inputElement} />
</label>
</div>
<div className={classes.inputBox}>
<label className={touched.phone && errors.phone ? [classes.label, classes.labelError].join(' ') : classes.label} >Mi número de teléfono es
<ErrorMessage name='phone' component='p' className={classes.error} />
<Field type='phone' name='phone' placeholder='Tu número de teléfono' autoComplete='tel' className={bgColor ? [classes.inputElement, classes[bgColor]].join(' ') : classes.inputElement} />
</label>
</div>
<div className={classes.inputBox}>
<label className={touched.company && errors.company ? [classes.label, classes.labelError].join(' ') : classes.label} >Trabajo en
<ErrorMessage name='company' component='p' className={classes.error} />
<Field type='text' name='company' placeholder='Tu compañía' autoComplete='organization' className={bgColor ? [classes.inputElement, classes[bgColor]].join(' ') : classes.inputElement} />
</label>
</div>
<div className={classes.inputBox}>
<label className={touched.message && errors.message ? [classes.label, classes.labelError].join(' ') : classes.label} >Mensaje
<ErrorMessage name='message' component='p' className={classes.error} />
<Field component='textarea' name='message' placeholder='Empieza a escribir...' autoComplete='off' className={bgColor ? [classes.textAreaElement, classes[bgColor]].join(' ') : classes.textAreaElement} />
</label>
</div>
<button type='submit'
className={classes.sendBtn}
disabled={isSubmitting || !isValid}
>
<span style={isSubmitting ? { display: 'none' } : null}>Enviar</span>
<div className={isSubmitting ? [classes['sk-circle'], classes.showing].join(' ') : classes['sk-circle']}>
<div className={[classes['sk-circle1'], classes['sk-child']].join(' ')}></div>
<div className={[classes['sk-circle2'], classes['sk-child']].join(' ')}></div>
<div className={[classes['sk-circle3'], classes['sk-child']].join(' ')}></div>
<div className={[classes['sk-circle4'], classes['sk-child']].join(' ')}></div>
<div className={[classes['sk-circle5'], classes['sk-child']].join(' ')}></div>
<div className={[classes['sk-circle6'], classes['sk-child']].join(' ')}></div>
<div className={[classes['sk-circle7'], classes['sk-child']].join(' ')}></div>
<div className={[classes['sk-circle8'], classes['sk-child']].join(' ')}></div>
<div className={[classes['sk-circle9'], classes['sk-child']].join(' ')}></div>
<div className={[classes['sk-circle10'], classes['sk-child']].join(' ')}></div>
<div className={[classes['sk-circle11'], classes['sk-child']].join(' ')}></div>
<div className={[classes['sk-circle12'], classes['sk-child']].join(' ')}></div>
</div>
<div style={this.state.checkSuccesBoxShow
? { display: 'inline-block' }
: { display: 'none' }} >
<Lottie
options={checkSuccessLottieOptions}
height={50}
width={50}
/>
</div>
</button>
</Form>
);
}
};
const ContactForm = withFormik({
mapPropsToValues({ name, email, phone, company, message }) {
return {
name: name || '',
email: email || '',
phone: phone || '',
company: company || '',
message: message || ''
}
},
validationSchema: Yup.object().shape({
name: Yup.string().required('El nombre es requerido'),
email: Yup.string().email('Email invalido').required('Email requerido'),
phone: Yup.number().typeError('Debe ser un número telefónico'),
company: Yup.string(),
message: Yup.string().required('Mensaje requerido')
}),
handleSubmit(values, { resetForm, setSubmitting }) {
// This is the endpoint we created in our API Gateway. This is where we make our POST request, which calls our Lambda function.
const endpoint = '***********';
// We replace line to keep format of text in message value
const messageText = values.message;
const formattedMessageText = messageText.replace(/\n/g, '<br />');
let newValues = { ...values };
newValues.message = formattedMessageText;
// Here, we instantiate our Request. This is a special object used by the Fetch API so it knows where to send data, what data to send, and how to send it.
var lambdaRequest = new Request(endpoint, {
method: 'POST',
// Quick note: 'no-cors' mode is for development on localhost only!
mode: 'no-cors',
body: JSON.stringify(newValues)
});
const that = this;
// Call the Fetch API to make our request
fetch(lambdaRequest)
.then(response => {
console.log(response)
resetForm();
setSubmitting(false);
that.checkSuccesBoxShowHandler();
})
.catch(err => console.log(err));
}
})(CForm)
export default ContactForm
因为您在 withFormik
内部,这是一个 HOC(高阶组件),您无法访问组件状态,因此您需要另一种方法。
您可以使用由 this.props.form.status
传递给您的组件的 setStatus
。
所以当你想显示按钮时,你调用 setStatus
带有一些标志或值,在你的组件中你做一个条件,所以 show/hide 它。
你可以在this issue where this answer your problem中看到这个问题。
对于你的情况,你需要做类似
的事情handleSubmit(values, { resetForm, setSubmitting, setStatus }) {
// Call the Fetch API to make our request
fetch(lambdaRequest)
.then(response => {
console.log(response)
resetForm();
setSubmitting(false);
setStatus(true); // setStatus to communicate with the component
that.checkSuccesBoxShowHandler();
})
.catch(err => console.log(err));
}
在你的组件中
{this.props.form.status && <Lottie
options={checkSuccessLottieOptions}
height={50}
width={50}
/>
}