我遇到了一个奇怪的问题。我有一个表单,在那里我有一个输入字段,但是在我用按键触发onChange事件后,它失去了输入字段的焦点。
{editPhoneEnabled && <Field
name="phoneNumber"
component={phoneFieldRenderer}
validate={[Validator.required, Validator.phone]}
/>}
const phoneFieldRenderer = ({ input }) => {
return (
<ReactTelInput {...input} />
)
}
我已经看到了这个例子的问题发生的设置(https://codepen.io/invisiblecomma/pen/wqLaZQ),但我已经做了类似的,你可以看到,但它仍然不工作?
有什么想法可以帮助我了解发生了什么事?
整个组件:
import React, { useState, useEffect } from 'react';
import { Field, reduxForm, getFormValues } from 'redux-form';
import { Col, FormGroup } from 'reactstrap';
import { t } from 'Utilities/i18n';
import Validator from 'Utilities/validation';
import Button from 'Components/Forms/Button';
import { connect } from 'react-redux';
import { gql, useMutation } from '@apollo/client';
import ReactTelInput from 'react-telephone-input';
const formName = 'PhoneVerifyForm';
const performPhoneVerificationMutation = gql`
mutation registerPage_userPhoneVerification($input: RegisterPhoneVerificationInput!) {
userPhoneVerification(input: $input) {
errors {
field
messages
}
phoneNumberVerificationSid
verified
}
}
`;
// TODO props: unconfirmedUserId, phoneNumberVerificationSid, initialValues, callback
const PhoneVerifyForm = (props) => {
const [editPhoneEnabled, setEditPhoneEnabled] = useState(false);
const [codeSend, setCodeSend] = useState(props.phoneNumberVerificationSid !== undefined);
const [performPhoneVerification, { data:performPhoneVerificationData }] = useMutation(performPhoneVerificationMutation);
const [errors, setErrors] = useState([]);
useEffect(() => {
if (performPhoneVerificationData && performPhoneVerificationData.userPhoneVerification) {
const {userPhoneVerification} = performPhoneVerificationData;
if(userPhoneVerification.errors.length === 0) {
setErrors([])
if (editPhoneEnabled) {
editPhoneEnabled(false);
}
setCodeSend(userPhoneVerification.phoneNumberVerificationSid !== undefined);
if(userPhoneVerification.verified !== undefined) {
props.callback(props.formValues.phone);
}
} else {
setErrors(userPhoneVerification.errors)
}
}
}, [performPhoneVerificationData, ])
function handleSubmit(values) {
if (editPhoneEnabled) {
// update phone number
return performPhoneVerification({
variables: {
input: {
unconfirmedUserId: props.unconfirmedUserId,
phone: values.phoneNumber,
},
},
});
} else if (!codeSend) {
// send new code
return performPhoneVerification({
variables: {
input: {
unconfirmedUserId: props.unconfirmedUserId,
channel: values.channel,
},
},
});
}
// else validate code
return performPhoneVerification({
variables: {
input: {
unconfirmedUserId: props.unconfirmedUserId,
code: values.code,
},
},
});
}
const handleEditPhone = () => {
setEditPhoneEnabled(!editPhoneEnabled);
setCodeSend(false);
};
const phoneFieldRenderer = ({ input }) => {
return (
<ReactTelInput {...input} />
)
}
return (
<form className="row" onSubmit={props.handleSubmit(handleSubmit)}>
{!codeSend && <Col style={{background: 'pink'}}>
<p>{t('select channel')}</p>
<FormGroup row className="indented-form-group">
<Col>
<label>
<Field
name="channel"
component="input"
type="radio"
value="sms"
validate={Validator.required}
/>
{t('Sms')}
</label>
</Col>
<Col xs={6}>
<label>
<Field
name="channel"
component="input"
type="radio"
value="phone"
validate={Validator.required}
/>
{t('phone')}
</label>
</Col>
</FormGroup>
</Col>}
{codeSend && <Col style={{background: 'yellow'}}>
<FormGroup row className="indented-form-group">
<Field
labelClassname="required"
label={t('Code')}
name="code"
component="input"
type="text"
validate={[Validator.required]}
/>
</FormGroup>
</Col>}
<Col style={{background: 'red'}}>
<FormGroup row className="indented-form-group">
{!editPhoneEnabled && <div>
<span>PHONE PLACEHOLDER</span><br />
<span onClick={handleEditPhone}>Edit phone number</span>
</div>}
{editPhoneEnabled && <Field
name="phoneNumber"
component={phoneFieldRenderer}
validate={[Validator.required, Validator.phone]}
/>}
</FormGroup>
</Col>
<Col>
<FormGroup row className="indented-form-group">
<Button submit disabled={props.submitting || props.invalid}>
{editPhoneEnabled ? t('Change phone number') : codeSend ? t('Validate code') : t('Send code')}
</Button>
</FormGroup>
</Col>
</form>
);
};
const mapStateToProps = state => ({
formValues: getFormValues(formName)(state) || {}, //This basically gives us the form values in the props and it gets updated on keydown.
});
const decoratedComponent = connect(mapStateToProps, null)(PhoneVerifyForm)
export default (reduxForm({
form: formName,
enableReinitialize: true,
shouldAsyncValidate: ({ trigger }) => ['blur'].includes(trigger),
})(decoratedComponent));
1条答案
按热度按时间7kqas0il1#
我也面临着同样的问题。
phoneFieldRenderer
函数放在组件之外(如@envy所述)。