使用样式化组件验证表单的行为不像CSS

时间:2019-09-01 05:43:42

标签: css reactjs forms styled-components

我找到了一个非常简单而有效的教程,仅使用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)上的预期行为:

  1. 按提交,输入将变为红色
  2. 填写一个输入=>会单独清理红色边框(这意味着一个输入状态不依赖于另一个)

要在第二个提琴上重现该问题(样式化组件):

  1. 按提交,输入将变为红色
  2. 填写一个输入=>发行=>输入(不再无效)保持红色,只要第二个输入仍然无效(这意味着两个输入相关)。
  3. li>

我的问题是,在样式组件版本中,当两个输入均有效时,将清除输入的红色边框。但我希望输入像CSS版本那样单独起作用。

我知道有100种解决方案可以解决该问题,但我真的很喜欢本教程简单,干净的解决方案。我期望双方都有相同的行为,这可能是错误吗?有什么我想念的吗?请帮助<3

0 个答案:

没有答案