我找到了一个非常简单而有效的教程,仅使用React和CSS即可处理表单验证和错误处理:https://medium.com/@everdimension/how-to-handle-forms-with-just-react-ac066c48bd4f
此解决方案的工作原理很吸引人。但是我想使用css-in-js库中的styled-components重现相同的行为。
处理本教程中的错误的解决方案是切换FORM的类,并针对输入子级的伪类:invalid,在输入周围应用红色边框。它仅使用CSS类即可完美工作。我尝试将相同的系统与样式化组件一起使用,但是出了错。
我做了2次小提琴来向您展示行为上的差异
js
const Form = () => {
const [error, setError] = React.useState(false)
const handleSubmit = React.useCallback((event) => {
event.preventDefault()
if (!event.target.checkValidity()) {
setError(true);
return;
}
setError(false)
console.log('Do something')
}, [error, setError])
return(
<div>
<h1>With pure CSS</h1>
<h2>Good behavior : </h2>
<h2>1 . Press submit => the input goes red </h2>
<h2>2 . Fill one of the input => cleans the red border individually</h2>
<form
onSubmit={handleSubmit}
noValidate
className={error ? "displayErrors" : ""}
>
<input className='input' required></input>
<input className='input' required></input>
<input type="submit" value="Submit!"></input>
</form>
</div>
)
}
ReactDOM.render(<Form />, document.querySelector("#app"))
css
.displayErrors input:invalid {
border-color: red;
}
const StyledInput = styled.input`
margin-right: 5px;
display: table-cell;
margin-bottom: 10px;
outline: none;
`
const StyledForm = styled.form`
&:invalid ${StyledInput} {
border-color: ${props => {
console.log(props.error)
return props.error ? "red" : "none"
}};
}
`;
const Form = () => {
const [error, setError] = React.useState(false)
const handleSubmit = React.useCallback((event) => {
event.preventDefault()
if (!event.target.checkValidity()) {
setError(true);
return;
}
setError(false)
console.log('Do something')
}, [error, setError])
return(
<div>
<h1>With Styled components</h1>
<h2>To reproduce the issue : </h2>
<h2>1 - press submit, the inputs goes red </h2>
<h2>2 - fill one input => ISSUE => the input (which is no more invalid) stays red </h2>
<StyledForm
onSubmit={handleSubmit}
noValidate
error={error}
>
<StyledInput className='input' required></StyledInput>
<StyledInput className='input' required></StyledInput>
<input type="submit" value="Submit!"></input>
</StyledForm>
</div>
)
}
ReactDOM.render(<Form />, document.querySelector("#app"))
第一个小提琴(CSS)上的预期行为:
要在第二个提琴上重现该问题(样式化组件):
我的问题是,在样式组件版本中,当两个输入均有效时,将清除输入的红色边框。但我希望输入像CSS版本那样单独起作用。
我知道有100种解决方案可以解决该问题,但我真的很喜欢本教程简单,干净的解决方案。我期望双方都有相同的行为,这可能是错误吗?有什么我想念的吗?请帮助<3