我正在构建一个表单 - 用户在进入下一个屏幕之前需要回答的一系列问题(单选按钮)。对于字段验证,我使用 yup(npm 包)和 redux 作为状态管理。
对于一个特定的场景/组合,在用户可以继续之前,会显示一个新屏幕 (div) 要求确认(复选框)。我想仅在显示时应用此复选框的验证。
如何使用 React 检查元素 (div) 是否显示在 DOM 中?
我想这样做的方法是将变量“isScreenVisible”设置为 false,如果满足条件,我会将状态更改为“true”。
我正在检查并在 _renderScreen() 中将“isScreenVisible”设置为 true 或 false,但由于某种原因它进入了无限循环。
我的代码:
class Component extends React.Component {
constructor(props) {
super(props);
this.state = {
formisValid: true,
errors: {},
isScreenVisible: false
}
this.FormValidator = new Validate();
this.FormValidator.setValidationSchema(this.getValidationSchema());
}
areThereErrors(errors) {
var key, er = false;
for(key in errors) {
if(errors[key]) {er = true}
}
return er;
}
getValidationSchema() {
return yup.object().shape({
TravelInsurance: yup.string().min(1).required("Please select an option"),
MobilePhoneInsurance: yup.string().min(1).required("Please select an option"),
Confirmation: yup.string().min(1).required("Please confirm"),
});
}
//values of form fields
getValidationObject() {
let openConfirmation = (this.props.store.Confirmation === true)? 'confirmed': ''
return {
TravelInsurance: this.props.store.TravelInsurance,
MobilePhoneInsurance: this.props.store.MobilePhoneInsurance,
Confirmation: openConfirmation,
}
}
setSubmitErrors(errors) {
this.setState({errors: errors});
}
submitForm() {
var isErrored, prom, scope = this, obj = this.getValidationObject();
prom = this.FormValidator.validateSubmit(obj);
prom.then((errors) => {
isErrored = this.FormValidator.isFormErrored();
scope.setState({errors: errors}, () => {
if (isErrored) {
} else {
this.context.router.push('/Confirm');
}
});
});
}
saveData(e) {
let data = {}
data[e.target.name] = e.target.value
this.props.addData(data)
this.props.addData({
Confirmation: e.target.checked
})
}
_renderScreen = () => {
const {
Confirmation
} = this.props.store
if(typeof(this.props.store.TravelInsurance) !== 'undefined' && typeof(this.props.store.MobilePhoneInsurance) !== 'undefined') &&
((this.props.store.TravelInsurance === 'Yes' && this.props.store.MobilePhoneInsurance === 'No') ||
(this.props.store.TravelInsurance === 'No' && this.props.store.MobilePhoneInsurance === 'Yes')){
this.setState({
isScreenVisible: true
})
return(
<div>
<p>Please confirm that you want to proceed</p>
<CheckboxField
id="Confirmation"
name="Confirmation"
value={Confirmation}
validationMessage={this.state.errors.Confirmation}
label="I confirm that I would like to continue"
defaultChecked={!!Confirmation}
onClick={(e)=> {this.saveData(e)} }
/>
</FormLabel>
</div>
)
}
else{
this.setState({
isScreenVisible: false
})
}
}
render(){
const {
TravelInsurance,
MobilePhoneInsurance
} = this.props.store
return (
<div>
<RadioButtonGroup
id="TravelInsurance"
name="TravelInsurance"
checked={TravelInsurance}
onClick={this.saveData.bind(this)}
options={{
'Yes': 'Yes',
'No': 'No'
}}
validationMessage={(this.state.errors.TravelInsurance) ? this.state.errors.TravelInsurance : null }
/>
<RadioButtonGroup
id="MobilePhoneInsurance"
name="MobilePhoneInsurance"
checked={MobilePhoneInsurance}
onClick={this.saveData.bind(this)}
options={{
'Yes': 'Yes',
'No': 'No'
}}
validationMessage={(this.state.errors.MobilePhoneInsurance) ? this.state.errors.MobilePhoneInsurance : null }
/>
this._renderScreen()
<ButtonRow
primaryProps={{
children: 'Continue',
onClick: e=>{
this.submitForm();
}
}}
</div>
)
}
}
const mapStateToProps = (state) => {
return {
store: state.Insurance,
}
}
const Insurance = connect(mapStateToProps,{addData})(Component)
export default Insurance