Home > Net >  How to run a function after setState, tried useEffect with dependency but it failed
How to run a function after setState, tried useEffect with dependency but it failed

Time:09-22

I have two problems here, but let me show you my code first

const [error, setError] = useState({error: "", title : ""})
const formInitialState = {
  title :{
    value : '',
    maxLength : 15,
    required : true,
    valid : false,
    message : "Your meal has no name, please select a name"
  },
  description : {
    value : '',
    required : true,
    maxLength : 100,
    valid : false,
    message : "Pitch [description] is required"
  },
}

I am trying to show an error to the user when he tries to submit the form. I am using useReducer to manage the form state and actions but using useState to manage the error..

Here is the problem

const submitHandler = (e) => {
  e.preventDefault();
  const isValid = checkValidity(formState);
  if (!isValid) {
    const wrongInput = Object.keys(formState).find((item) => !formState[item].valid);
    return setError({
      title: formState[wrongInput].title,
      error: formState[wrongInput].message,
    });
  }

  // do something if its valid...
};

what i want to achieve here is, when a user submits an invalid form it sets the error state to the error message and the set the showModal state [which toggles the modal visibility] to true. in the modal i get values from the error state and display it on the Modal,therefore i want setShowModal to run only when the setError has completed, i know better to add the code directly below it so i added it to useEffect with error as a dependency but it still didn't work

useEffect(()=> setShowModal(true), [error])

In the react developer tools i can see clearly that the modal is called before the values reflect on the error state

Question 2
Why does the useEffect run on load of the page even though i gave it an error dependency? It sets my modal to true on initial load then waits for the error to change after that, how can i stop this?

Thank you all in advance

CodePudding user response:

useEffect is run each time its dependencies update, but also on the initial render. If you want the modal to be shown only when error is present, you'll need to add a condition to the hook:

useEffect(() => {
  if (error !== '') {
    setShowModal(true);
  }
}, [error]);

Or more concise:

useEffect(() => setShowModal(Boolean(error)), [error])

CodePudding user response:

Ans 1: Display the modal based on a check(condition)

useEffect(()=> {
  if(someHelperFunction(error))
    setShowModal(true)
}, [error])

Ans 2: It runs when the component mounts because, initially when you use the useState(initializer), It is changing the state from undefined to initializer.

Hope this helps.

CodePudding user response:

Q1: You could do :

useEffect(()=>  if (!!error.error){ setShowModal(true)}, [error])

Q2: UseEffect runs every time a variable in the dependency array is changed, on the first render it runs once

  • Related