whole app resets if I dispatch action on submit , but it is ok if I dispatch the same action on the load of component

Viewed 53

I need to dispatch an action with the form content. The action has some async component handled by my middleware The action works fine outside of react, when setting the initial data.

The action works fine if I use it inside an useEffect() with no dependencies so it will run straight away... the store gets updated ad the api calls work.

import { React, useState, useEffect } from "react"
import { useSelector, useDispatch } from "react-redux"
import { apiCallBegan } from "../store/api"

const NewQuestionForm = () => {
  // const [optionOneText, setOptionOneText] = useState("")
  // const [optionTwoText, setOptionTwoText] = useState("")
  const [submitted, setSubmitted] = useState(false);
  // const author = useSelector(state => state.auth)
  const dispatch = useDispatch()

useEffect(()=>{
  dispatch(apiCallBegan({
    callMethodName: '_saveQuestion',
    data: { optionOneText: "I believe I can fly", optionTwoText: "I donte believe I can Fly", author:'helenfoneing' },
    onSuccess: ['questions/questionAdded','users/questionAdded'],
    onError: 'apiRequestfailed'
  }
  ))
},[])

   return (
    <form className="new-question-form"
    // ... rest of component

    </form>)
}

but if I try to trigger form action upon submission of form , the whole app gets reset, just like pressing F5 on the browser:

/* eslint-disable no-unused-vars */
/* eslint-disable react/prop-types */ // TODO: upgrade to latest eslint tooling

import { React, useState, useEffect } from "react"
import { useSelector, useDispatch } from "react-redux"
import { apiCallBegan } from "../store/api"

const NewQuestionForm = () => {
  const [optionOneText, setOptionOneText] = useState("")
  const [optionTwoText, setOptionTwoText] = useState("")
  const [submitted, setSubmitted] = useState(false);
  const author = useSelector(state => state.auth)
  const dispatch = useDispatch()

useEffect(()=>{
  submitted && dispatch(apiCallBegan({
    callMethodName: '_saveQuestion',
    data: { optionOneText: "I believe I can fly", optionTwoText: "I donte believe I can Fly", author:'helenfoneing' },
    onSuccess: ['questions/questionAdded','users/questionAdded'],
    onError: 'apiRequestfailed'
  }
  ))
},[submitted])

  return (
    <form className="new-question-form"
    onSubmit={(e)=>{
      setSubmitted(true)
      e.preventDefault}}
      >
      NEW QUESTION FORM HERE
      <label>1.
        <input type="text"
          value={optionOneText}
          onChange={(e) => setOptionOneText(e.target.value)} />
      </label>
      <label>2.
        <input type="text"
          value={optionTwoText}
          onChange={(e) => setOptionTwoText(e.target.value)} />
      </label>
      <input type="submit" />
    </form>)
}


export default NewQuestionForm

I am not sure what the problem is. The action data is hardwire to isolate the problem

1 Answers

You are facing this issue because for this line submitted && dispatch(apiCallBegan

Explanation:

You are using short circuit syntax to check the submitted value in useEffect hooks. Let's take a look at the short circuits again, it compares the submitted value and if it was true it returns the right-side codes. more info on MDN documentation.

the useEffect will look like this if the submitted value was true:

useEffect( ()=> {
  return dispatch(apiCallBegan({
    callMethodName: '_saveQuestion',
    data: { optionOneText: "I believe I can fly", optionTwoText: "I donte believe I can Fly", author:'helenfoneing' },
    onSuccess: ['questions/questionAdded','users/questionAdded'],
    onError: 'apiRequestfailed'
  }
))

As you see, you are returning the dispatch function which is not your expectation and was causing the problem.

You are using dispatching on cleanup of useEffect which is not correct.

The Solution:

Try to calling the dispatch function in your useEffect instead of returning it:

useEffect(() => {
  if (submitted) { 
    dispatch(apiCallBegan({
      callMethodName: '_saveQuestion',
      data: { optionOneText: "I believe I can fly", optionTwoText: "I don't believe I can Fly", author:'helenfoneing' },
      onSuccess: ['questions/questionAdded','users/questionAdded'],
      onError: 'apiRequestfailed'
    }))
  }
} , [submitted])
Related