#javascript #reactjs #forms #react-router #use-state
Вопрос:
Я работаю над формой в проекте электронной коммерции React.
Вот как это должно работать: когда пользователь заполняет форму и нажимает кнопку «Отправить», я хочу отправить данные формы на сервер и перенаправить пользователя на страницу подтверждения/благодарности.
К сожалению, когда я заполняю форму и нажимаю кнопку «Отправить», следующий код работает определенным образом:
1 — й щелчок-он отправляет данные, но «setSubmitted(true)» не работает, поэтому я не перенаправлен
2-й клик — это снова отправляет данные, setSubmitted работает, и я перенаправлен
Не могли бы вы рассказать мне, как исправить код?
let history = useHistory(); const [submitted, setSubmitted] = useState(false); const handleSubmit = (e) =gt; { e.preventDefault(); fetch('http://localhost:8000/orders', { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ cart: 1 }), //dummy data }) .then((response) =gt; { setSubmitted(true); return response.json(); }) .then(() =gt; { if (submitted) { return history.push('/thank-you-page'); } }); }; return ( lt;form onSubmit={handleSubmit}gt; ... lt;/formgt; );
Ответ №1:
setState
является асинхронным действием и вызовет повторную визуализацию. Поэтому шаги, что ваш компонент переживает по первому клику заключается в том, что ее устанавливает государство и возвращает JSON, что означает, что в точке, второй .then()
выполняется (в первый рендер), представленном по-прежнему ложь, на второй рендер, когда вы нажимаете второй раз, представленных устанавливается в True с предыдущей кнопкой, и так же история толчок.
Поскольку вы используете это состояние только для проверки перехода на следующую страницу, вы можете заменить его именем пользователя, но лично я был бы склонен переписать его так, чтобы избежать путаницы:
const handleSubmit = async (e) =gt; { e.preventDefault(); try { const response = await fetch('http://localhost:8000/orders', { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ cart: 1 }), //dummy data }); // setSubmitted(true); // set this still if you need it elsewhere history.push('/thank-you-page'); // return response.json(); // only return this if you need it to be used somewhere } catch(error) { // handleTheErrorSomehow(error) } };
Ответ №2:
Вам нужно удалить if statement
со 2-го, затем (…), так как обновление состояния выполняется асинхронно, и в первый раз щелкните его false
. И когда вы снова нажмете «Отправлена форма», а затем «отправлена», на этот раз это соответствует вашему последнему действию, и вы перенаправлены.
И еще одно, если вы используете возврат данных с использованием первого then(...)
блока, вы можете также поместить свой код перенаправления и удалить второй.
const handleSubmit = (e) =gt; { e.preventDefault(); fetch('http://localhost:8000/orders', { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ cart: 1 }), //dummy data }) .then((response) =gt; { setSubmitted(true); return history.push('/thank-you-page'); }); };
Надеюсь, это поможет вам решить вашу проблему.