【问题标题】:Submit button in a form works after the second click. ReactJS表单中的提交按钮在第二次单击后起作用。反应JS
【发布时间】:2021-10-27 11:07:00
【问题描述】:

我正在 React 电子商务项目中处理表单。

它的工作原理如下:当用户填写表单并单击提交按钮时,我想将表单数据发布到服务器并将用户重定向到确认/感谢页面。

不幸的是,当我填写表格并单击提交按钮时,以下代码以特定方式工作:

第一次点击 - 它发送数据但“setSubmitted(true)”不起作用所以我没有被重定向

第二次点击 - 再次发送数据,setSubmitted 工作,我被重定向

您能告诉我如何修复代码吗?

let history = useHistory();
const [submitted, setSubmitted] = useState(false);


const handleSubmit = (e) => {

e.preventDefault();

fetch('http://localhost:8000/orders', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({ cart: 1 }), //dummy data
})
  .then((response) => {
    setSubmitted(true);
    return response.json();
  })
  .then(() => {
    if (submitted) {
      return history.push('/thank-you-page');
    }
  });
};

  return (
  <form onSubmit={handleSubmit}> ... </form>
  );

【问题讨论】:

    标签: javascript reactjs forms react-router use-state


    【解决方案1】:

    setState 是一个异步操作,会导致重新渲染。 因此,您的组件在第一次单击时所经历的步骤是它设置状态并返回 json,这意味着在执行第二个 .then() 时(在第一次渲染上)提交仍然是错误的,由当您第二次单击时,第二次渲染从上一次单击将提交设置为 true,然后它会执行历史推送。

    由于您仅使用此状态来检查是否推送到下一页,您可以将其替换为 useRef,但我个人倾向于这样重写它以避免任何混淆:

    const handleSubmit = async (e) => {
        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】:

      您需要从第二个 then(...) 中删除 if statement,因为状态更新是异步运行的,并且第一次单击它是 false。当您再次单击提交的表单然后提交时,这次从您的最后一个操作开始为真,并且您重定向了。

      如果您使用从第一个 then(...) 块返回的 using 数据,您也可以将它们的代码重定向并删除第二个。

      const handleSubmit = (e) => {
      
      e.preventDefault();
      
      fetch('http://localhost:8000/orders', {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
        },
        body: JSON.stringify({ cart: 1 }), //dummy data
      })
        .then((response) => {
          setSubmitted(true);
          return history.push('/thank-you-page');
        });
      };
      

      希望这能解决您的问题。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-06-13
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多