shadaj/slinky

Issue with updating state for two forms.

Open-eXul opened this issue · 3 comments

I have a stateful component that has two login forms. Whenever one form changes it is supposed to determine if the input is valid and will tell you if it is. This is working for both forms:

@react class App extends Component {
  type Props = Unit
  case class State(_1: String, _2: String)

  override def initialState: State = State("", "")

  private val css = AppCSS

  def render() = {
    div()(
      div()(
        input(
          `type` := "email",
          onChange := (event => {
            setState(State(event.target.value, initialState._2))
          }),
          className := 
            (if (state._1.length > 3 && state._1.length <= 149)
              "form-control is-valid"
            else
              "form-control is-invalid")
        ),
        (
          if (state._1.length > 3 && state._1.length <= 149)
            div(className := "valid-feedback")("Email is Valid")
          else
            div(className := "invalid-feedback")("Email is Invalid")
        )
      ),
      div()(
        input(
          `type` := "password",
          onChange := (event => {
            setState(State(initialState._1, event.target.value))
          }),
          className := 
            (if (state._2.length > 3 && state._2.length <= 99)
              "form-control is-valid"
            else
              "form-control is-invalid")
        ),
        (
          if (state._2.length > 3 && state._2.length <= 99)
            div(className := "valid-feedback")("Password is Valid")
          else
            div(className := "invalid-feedback")("Password is Invalid")
        )
      )
    )
  }
}

The problem is that if I provide input to one form and it turns green if the condition is true. The other will turn false even if the input is valid. That is, changes to one form changes the validation status of the other. This makes it impossible to have both forms show valid at the same time. This makes no sense so I thought I would make an issue. I could be wrong though because I have not been using slinky for very long.

If I am wrong then any help would be greatly appreciated.

Thanks!

I can think about these calls being the problem setState(State(initialState._1, event.target.value)), you should not depend in the current state but in the one provided by the setState function, like setState(_.copy(_2 = event.target.value)).

Check the react docs to understand more about it.

Also, checkout this example for handling form validation.

@AlexITC That just gave me the following error: Uncaught TypeError: event.target is null. I also tried setState(value => State(value._1, event.target.value)) which failed too with the same error.

@Open-eXul you'll need to call persist on the event, see https://reactjs.org/docs/legacy-event-pooling.html