反应/反应挂钩:当用户取消选中复选框时,需要触发输入验证

时间:2019-06-10 18:23:17

标签: javascript reactjs onclick react-hooks

我有一个带有输入字段和复选框的组件。就目前而言,该复选框将禁用输入字段并清除所有验证错误。我要尝试做的是创建其他功能,如果有人取消选中该框并且输入再次变为活动状态,将运行验证,并再次提示用户输入电子邮件。例如,我有一个代码沙箱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 &nbsp;
          </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

1 个答案:

答案 0 :(得分:1)

您的代码存在一些问题:

  1. 为什么仅在onBlur上验证输入
  2. 为什么该复选框具有清除输出的副作用?为此添加一个按钮。
  3. 煮沸陷阱代码太多。

这是一个最小的示例,您应该从这里弄清楚适合自己的地方:

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的演示:

Edit flamboyant-newton-mhjq7