首页 > 解决方案 > 对输入验证做出反应初始状态

问题描述

关于如何在验证输入上设置初始状态,我一直在苦苦思索一个多小时。

这是我的代码示例:

const {useReducer, useEffect, useState} = React;

const BasicInput = props => {
	const [isValidated, setIsValidated] = useState(true)

	useEffect(() => {
			setIsValidated(props.validation)
      console.log(props.validation)
	},[props.validation])
	
	return (
		<div className='input-box'>			
			<input
        className={`${!isValidated && 'not-valid'}`}
				type='text'
				name={props.name}
				required
				onChange={props.handleInput}
			/>
		</div>
	)
}

function contactFormReducer(state, action) {
	switch (action.type) {
		case 'email':
			return {...state, name: {
				value: action.payload,
				isValidate: /^.+(@).*\.[a-z]{2}$/.test(action.payload)
			}}
	}
}

const ExampleForm = () => {
	const [formData, dispatch] = useReducer(contactFormReducer, {
		name: {
			value: null,
			isValidate: false
		}
	})

	return (	
					<BasicInput						
						name='email'
						label='label'
						handleInput={e => dispatch({type: 'email', payload: e.target.value})}
						validation={formData['name'].isValidate}
					/>
	)
}

ReactDOM.render(
  <ExampleForm title="Example using simple hook:" />,
  document.getElementById("root")
);
.not-valid {
	border: 2px solid red;
	color: red!important;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.4/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.4/umd/react-dom.production.min.js"></script>
<div id='root'>
</div>

如您所见,初始输入状态设置为无效,这没关系,但对于第一次显示的表单而言,它看起来很糟糕。我想知道如何不设置样式not-valid,同时在第一次渲染时保持验证为假。我需要对此有一些新的见解,非常感谢任何帮助和建议。

更新

就在我发表这篇文章之后,我找到了非常满意的解决方案,但我仍然对性能不满意:

const {useReducer, useEffect, useState} = React;

const BasicInput = props => {
	const [isValidated, setIsValidated] = useState(true)
  const [isFocus, setIsFocus] = useState(false)
  
  useEffect(() => {
		if (isFocus) {
			setIsValidated(props.validation)
      console.log(props.validation)
		}
	})

	const handleFocus = () => {		
		setIsFocus(true)
	}
	
	return (
		<div className='input-box'>			
			<input
        className={`${!isValidated && 'not-valid'}`}
				type='text'
				name={props.name}
				required
				onChange={props.handleInput}
        onFocus={handleFocus}
			/>
		</div>
	)
}

function contactFormReducer(state, action) {
	switch (action.type) {
		case 'email':
			return {...state, name: {
				value: action.payload,
				isValidate: /^.+(@).*\.[a-z]{2}$/.test(action.payload)
			}}
	}
}

const ExampleForm = () => {
	const [formData, dispatch] = useReducer(contactFormReducer, {
		name: {
			value: null,
			isValidate: false
		}
	})

	return (	
					<BasicInput						
						name='email'
						label='label'
						handleInput={e => dispatch({type: 'email', payload: e.target.value})}
						validation={formData['name'].isValidate}
					/>
	)
}

ReactDOM.render(
  <ExampleForm title="Example using simple hook:" />,
  document.getElementById("root")
);
.not-valid {
	border: 2px solid red;
	color: red!important;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.4/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.4/umd/react-dom.production.min.js"></script>
<div id='root'>
</div>

onChange每次触发事件时,此解决方案都会重新渲染我的输入组件。知道如何预防吗?

标签: javascriptreactjsvalidationreact-hooks

解决方案


推荐阅读