0

I'm new to react hooks and have run into a situation which I solved, but not sure if this is a proper implementation of useEffect. I have a form with some fields (answer, question etc) with some validation, but without the implementation of useEffect below, my validation was one step behind due to the async nature of setting state. After adding useEffect and the state items to the useEffect dependency array that was fixed. But the side effect of adding items to that array was re-rendering, and thus fetchData running each time the state changed. Each time fetch data finished it wiped out the changed state of any items I was changing in the form.

My solution was a "mounted" state variable which is set to true once the fetch occurs. Then if mounted was true, I don't fetch again. This solution seems to have fixed the re-fetching issue as well as the state being one step behind. Is this a proper pattern to use or is there a better/more preferred way?

  const [mounted, setMounted] = useState(false)
  useEffect(() => {// reactive state  
    // if params.id that means we need to edit an existing faq
    if(params.id && !mounted){
      async function fetchData() {
        await fetchFaqs();
        setMounted(true);
      }
      fetchData();
    }
    checkIfFormIsValid();
  }, [answer, question, section, sort, checkIfFormIsValid]);
2
  • You probably want to cache this data rather than have it fetch on every render, even if you've managed to prevent too many re-renders. One quick-and-easy way to implement would be through a RecoilJS async selector. See the async example here: recoiljs.org/docs/guides/asynchronous-data-queries Commented Dec 1, 2022 at 1:26
  • Thanks for the comment. Yeah with this code it is only fetching the data once. Commented Dec 1, 2022 at 14:41

1 Answer 1

1

You could just use separate useEffects like this:

// add params.id to dependency array
useEffect(() => {
  if (params.id) {
    async function fetchData() {
      await fetchFaqs();
    }
    fetchData();
  }
}, [params.id])

useEffect(() => {
  checkIfFormIsValid();
}, [answer, question, section, sort, checkIfFormIsValid])
Sign up to request clarification or add additional context in comments.

1 Comment

Thank you Enes. Interesting. I'm coming from the componentDidMount world so was only thinking of using useEffect once.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.