我需要你的帮助。 当我在Formik中使用promise提交表单时,我试图使用React的状态在表单的发送按钮中显示/隐藏div。我知道它与绑定“ 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
答案 0 :(得分:0)
由于您位于HOC(高阶组件)withFormik
中,因此无法访问组件状态,因此需要另一种方法。
您可以使用setStatus
传递给组件的this.props.form.status
。
因此,当您要显示按钮时,请使用一些标志或值调用setStatus
,并在组件中执行条件操作,以便显示/隐藏它。
您可以在this issue的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}
/>
}