-1

I want to prevent a form submission event ONLY IF the form contains errors, if there isn't any, the event shouldn't be prevented.

This's my current code, it's not working because state still isn't updated when if (state.error === true) check is happening.

I'm also using react-router with its useFetcher() hook. So instead of <form>, I'm using fetcher.Form, but I guess it doesn't matter?


export default function App() {
  const [state, dispatch] = useReducer(formReducer, {error: null});

  return (
    <div className="App">
      <form onSubmit={onSubmit}>
        <button>btn</button>
      </form>
    </div>
  );

  function onSubmit(ev) {
    dispatch({type: 'submitted'});
    console.log(state.error);  // still not updated, logs 'null'
    if (state.error === true) {
      ev.preventDefault(); // prevent or not prevent depending on dispatch
    }
  }
  
  function formReducer(state, action) {
    switch(action.type) {
      case 'submitted': {
        let error = true; // here will be a validation function
    // if error is going to be true, form submission should be prevented

        return {...state, error: error};
      }
      default: 
        return state;
    }
  }
}

Live code: https://codesandbox.io/s/young-fire-72dmxt?file=/src/App.js

Drew Reese
  • 165,259
  • 14
  • 153
  • 181
Serguei A
  • 334
  • 1
  • 2
  • 10

1 Answers1

1

Yeah, you cant do it this way. It seems like you are aware that react batches its state updates. What you could do is disable the form by default then only enable it when there are no errors. You might want a validate type thing in your reducer which fires after form fields are updated. As you eluded too, onSubmit will be too late in the process.

terpinmd
  • 1,014
  • 8
  • 15