简体   繁体   中英

Strange order of execution react

Bellow is a function, handleSubmit, which is triggered when a user clicks the submit button of my form. Within this function it calls the requiredInputs function that checks if all the form values (which i have stored in state) are empty. If empty I want to set some error variables (also stored in state) to true so my program can respond accordingly. However the first time the user clicks submit and there are empty fields, the error variables are not updated before the if condition is checked leading to the form to be submitted. Subsequent invalid submission attempts are blocked though, which means the variables are updated after the submission if check is done... any idea why this behaviour is occuring?

Thanks

function handleSubmit() {
    requiredInputs()
    if (!titleError && !classificationError && !descriptionError) {     
      ### Entering this if statement on first click of submit when above variables should be set to true
      props.submit(title,classification,description,collaborators)
      setTitle("")
      setClassification("")
      setDescription("")
      setCollaborators([])
    }
  }

function requiredInputs () {
  if (title.length<1) setTitleError(true)
  if (description.length<1) setDescriptionError(true)
  if (classification.length<1) setClassificationError(true)
}

You are trying to access state variable immediately after setting them. Which is not possible because state updates are asynchronous. Though class based components provide setState callback like this.setState({titleError: true}, callback) , where callback will have updated state but same is not possible in functional components. In this case, you can try to return some boolean from requiredInputs function.

 function handleSubmit() { const hasError = requiredInputs() if (hasError) return props.submit(title,classification,description,collaborators); setTitle("") setClassification("") setDescription("") setCollaborators([]) } } function requiredInputs () { let hasError=false if (title.length<1){ hasError=true setTitleError(true) } if (description.length<1){ hasError=true setDescriptionError(true) } if (classification.length<1){ hasError = true setClassificationError(true) } return hasError }

The reason behing this is that setState is asynchronous in React

setState() does not immediately mutate this.state but creates a pending state transition. Accessing this.state after calling this method can potentially return the existing value. There is no guarantee of synchronous operation of calls to setState and calls may be batched for performance gains.

If you want to use the values of state just after the setState you can use the callback function in Class components but for functional components you have use useEffect hook

useEffect(() => {
   if (!titleError && !classificationError && !descriptionError) {     
        props.submit(title,classification,description,collaborators)
        setTitle("")
        setClassification("")
        setDescription("")
        setCollaborators([])
},[TitleError,classificationError,descriptionError])

Now you just need to call requiredInputs function

function handleSubmit() {
    requiredInputs()
  }

requiredInputs function will update the TitleError, classificationError and descriptionError which will trigger the useEffect hook and you will have your desired effect

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM