React/React 挂钩:需要在用户取消选中复选框时触发输入验证
React/React Hooks: Need to trigger validation for input when a user unchecks a checkbox
我有一个带有输入字段和复选框的组件。就目前而言,复选框会禁用输入字段并清除所有验证错误。我想做的是创建额外的功能,如果有人取消选中该框并且输入再次变为活动状态,验证将 运行 并再次提示用户输入电子邮件。例如,我有一个代码沙箱 here,下面列出了我的完整组件
import React from 'react'
import PropTypes from 'prop-types'
import styled from 'styled-components'
import {
Col, Row, Icon, Input, Tooltip
} from 'antd'
import Checkbox from '../elements/Checkbox'
import Markup from '../core/Markup'
function validateEmail(value) {
const errors = {}
if (value === '') {
errors.email = 'Email address is required'
} else if (!/\S+@\S+\.\S+/.test(value)) {
errors.email = 'Email address is invalid'
}
return errors
}
const CustomerDetails = ({ customer }) => {
const { contact = {}, account = {}, site = {} } = customer || {}
const [disableInput, setDisableInput] = React.useState(false)
const [errors, setErrors] = React.useState({})
const [inputValue, setInputValue] = React.useState(contact.email)
function onBlur(e) {
setErrors(validateEmail(e.target.value))
}
function clearInput() {
setInputValue(' ')
}
function handleInputChange(event) {
setInputValue(event.target.value)
}
function CheckboxClick() {
if (!disableInput) {
clearInput()
}
setDisableInput(prevValue => !prevValue)
setError({})
}
return (
<Container>
<Row>
<Col span={10}>
<h4>
PRIMARY CONTACT EMAIL
</h4>
</Col>
</Row>
<Row>
<Col span={8}>
<StyledInput
value={inputValue}
onChange={handleInputChange}
disabled={disableInput}
onBlur={onBlur}
isError={!!errors.email}
/>
{errors.email && <ErrorDiv>{errors.email}</ErrorDiv>}
</Col>
<Col span={2} />
<Col span={8}>
<StyledCheckbox
value={disableInput}
onChange={CheckboxClick}
/> EMAIL
OPT OUT{' '}
</Col>
</Row>
</Container>
)
}
const Container = styled.div`
text-align: left;
`
const StyledCheckbox = styled(Checkbox)`
&&& {
background: white;
input + span {
width: 35px;
height: 35px;
border: 2px solid ${({ theme }) => theme.colors.black};
}
input + span:after {
width: 12.5px;
height: 20px;
}
input:focus + span {
width: 35px;
height: 35px;
}
}
`
const ErrorInput = ({ isError, ...remainingProps }) => (
<Input {...remainingProps} />
)
ErrorInput.propTypes = {
isError: PropTypes.bool
}
const StyledInput = styled(Input)`
max-width: 100%;
background: white;
&&& {
border: 2px solid ${props => (props.isError ? '#d11314' : 'black')};
border-radius: 0px;
height: 35px;
}
`
const ErrorDiv = styled.div`
color: #d11314;
`
export default CustomerDetails
您的代码存在一些问题:
- 为什么只在
onBlur
上验证输入
- 为什么复选框对清除输出有副作用?为其添加一个按钮。
- 沸腾陷阱代码太多。
这是一个最小的例子,你应该从这里找出适合你的:
const CustomerDetails = () => {
const [email, setEmail] = useState('');
const [disabled, setDisabled] = useState(false);
const [isValid, setIsValid] = useState(false);
const [showMsg, setShowMsg] = useState(true);
return (
<div className="App">
Insert "hello"
<Row>
<Input
value={email}
onChange={e => {
setEmail(e.target.value);
setIsValid(isValidEmail(e.target.value));
}}
disabled={disabled}
/>
</Row>
<Row>{!isValid && showMsg && 'Email is invalid'}</Row>
<Row type="flex" justify="space-between">
<Col>
<Checkbox
value={!disabled}
onChange={() => {
setDisabled(prev => !prev);
setShowMsg(prev => !prev);
setIsValid(isValidEmail(''));
setEmail('');
}}
/>{' '}
EMAIL OPT OUT
</Col>
</Row>
</div>
);
};
验证单词 hello
的演示:
我有一个带有输入字段和复选框的组件。就目前而言,复选框会禁用输入字段并清除所有验证错误。我想做的是创建额外的功能,如果有人取消选中该框并且输入再次变为活动状态,验证将 运行 并再次提示用户输入电子邮件。例如,我有一个代码沙箱 here,下面列出了我的完整组件
import React from 'react'
import PropTypes from 'prop-types'
import styled from 'styled-components'
import {
Col, Row, Icon, Input, Tooltip
} from 'antd'
import Checkbox from '../elements/Checkbox'
import Markup from '../core/Markup'
function validateEmail(value) {
const errors = {}
if (value === '') {
errors.email = 'Email address is required'
} else if (!/\S+@\S+\.\S+/.test(value)) {
errors.email = 'Email address is invalid'
}
return errors
}
const CustomerDetails = ({ customer }) => {
const { contact = {}, account = {}, site = {} } = customer || {}
const [disableInput, setDisableInput] = React.useState(false)
const [errors, setErrors] = React.useState({})
const [inputValue, setInputValue] = React.useState(contact.email)
function onBlur(e) {
setErrors(validateEmail(e.target.value))
}
function clearInput() {
setInputValue(' ')
}
function handleInputChange(event) {
setInputValue(event.target.value)
}
function CheckboxClick() {
if (!disableInput) {
clearInput()
}
setDisableInput(prevValue => !prevValue)
setError({})
}
return (
<Container>
<Row>
<Col span={10}>
<h4>
PRIMARY CONTACT EMAIL
</h4>
</Col>
</Row>
<Row>
<Col span={8}>
<StyledInput
value={inputValue}
onChange={handleInputChange}
disabled={disableInput}
onBlur={onBlur}
isError={!!errors.email}
/>
{errors.email && <ErrorDiv>{errors.email}</ErrorDiv>}
</Col>
<Col span={2} />
<Col span={8}>
<StyledCheckbox
value={disableInput}
onChange={CheckboxClick}
/> EMAIL
OPT OUT{' '}
</Col>
</Row>
</Container>
)
}
const Container = styled.div`
text-align: left;
`
const StyledCheckbox = styled(Checkbox)`
&&& {
background: white;
input + span {
width: 35px;
height: 35px;
border: 2px solid ${({ theme }) => theme.colors.black};
}
input + span:after {
width: 12.5px;
height: 20px;
}
input:focus + span {
width: 35px;
height: 35px;
}
}
`
const ErrorInput = ({ isError, ...remainingProps }) => (
<Input {...remainingProps} />
)
ErrorInput.propTypes = {
isError: PropTypes.bool
}
const StyledInput = styled(Input)`
max-width: 100%;
background: white;
&&& {
border: 2px solid ${props => (props.isError ? '#d11314' : 'black')};
border-radius: 0px;
height: 35px;
}
`
const ErrorDiv = styled.div`
color: #d11314;
`
export default CustomerDetails
您的代码存在一些问题:
- 为什么只在
onBlur
上验证输入
- 为什么复选框对清除输出有副作用?为其添加一个按钮。
- 沸腾陷阱代码太多。
这是一个最小的例子,你应该从这里找出适合你的:
const CustomerDetails = () => {
const [email, setEmail] = useState('');
const [disabled, setDisabled] = useState(false);
const [isValid, setIsValid] = useState(false);
const [showMsg, setShowMsg] = useState(true);
return (
<div className="App">
Insert "hello"
<Row>
<Input
value={email}
onChange={e => {
setEmail(e.target.value);
setIsValid(isValidEmail(e.target.value));
}}
disabled={disabled}
/>
</Row>
<Row>{!isValid && showMsg && 'Email is invalid'}</Row>
<Row type="flex" justify="space-between">
<Col>
<Checkbox
value={!disabled}
onChange={() => {
setDisabled(prev => !prev);
setShowMsg(prev => !prev);
setIsValid(isValidEmail(''));
setEmail('');
}}
/>{' '}
EMAIL OPT OUT
</Col>
</Row>
</div>
);
};
验证单词 hello
的演示: