【问题标题】:Using React Javascript (Form-Onsubmit & calling API not working properly)使用 React Javascript(Form-Onsubmit 和调用 API 无法正常工作)
【发布时间】:2020-10-14 13:37:22
【问题描述】:

阅读下面的代码时,我对逻辑有点困惑,虽然代码可以正常工作,但并不完全符合我的预期。

如果有人可以澄清一下,我有 3 个疑问。

1- 据我了解 useEffect 用于在渲染后调用函数,但在下面的代码中,一旦表单被汇总(onSubmit={credentialVerify}),它将调用如下 credentialVerify() 函数,所以我不认为我们在这里需要 useEffect,但除非我使用 useEffect 语句,否则代码仍然不会调用 API。

2- 也不等我先输入我的凭据,一旦我进入登录页面,它就会获取 API(使用 useEffect 时)并在窗口中显示结果,但我尝试在这样当我单击按钮时它将获取 API

3- 当以 onsubmit 形式调用 credentialVerify 函数时,我有 console.log(e) 但它显示为未定义,但据我所知 onsubmit 将调用该函数并默认通过事件参数。

下面是我的代码的 sn-p。

感谢任何帮助。

import React, { useState, useEffect } from "react";
    import "../App.css";
    import { Link } from "react-router-dom";

    function Signin() {
      const [name, setName] = useState("");
      const [password, setPassword] = useState("");
      const updateName = (e) => {
        setName(e.target.value);
      };
      const updatePassword = (e) => {
        setPassword(e.target.value);
      };
      const [items, setItems] = useState([]);
      useEffect(() => {              //Point-1  useEffect- API not call atall without this statement
        credentialVerify();
      }, []);
      const credentialVerify = async (e) => {
        console.log(e);                                         //Point-3 this is coming as undefined
        const data1 = await fetch("http://localhost:5000/api/customers");
        const incomingdata = await data1.json();
        console.log(data1);
        console.log(incomingdata);
        console.log(name, password);
        setItems(incomingdata);
      };
      return (
        <div>
          <div>
            {
              <form className="formstyle" onSubmit={credentialVerify}>
                <input
                  type="text"
                  placeholder="Username"
                  name="username"
                  value={name}
                  onChange={updateName}
                />
                          
                <input
                  type="text"
                  placeholder="Password"
                  name="password"
                  value={password}
                  onChange={updatePassword}
                />
                <button type="submit">Submit</button>
              </form>
            }
          </div>
          <div>
           
            {items.map((entry) => {
              let key = entry.email;
              let valuefirst = entry.firstName;
              let valuelast = entry.created_at;
            
              return (
                <p key={key}>
                  {key}: {valuefirst}bb {valuelast}
                </p>
              );
            })}
          </div>
        </div>
      );
    }
    export default Signin;

【问题讨论】:

    标签: javascript reactjs forms api async-await


    【解决方案1】:

    对于您的 first 问题,您是正确的 - 当您的组件第一次呈现时调用 credentialVerify 是没有意义的,因为这似乎是您的表单获取时的处理程序提交。除非您在显示表单之前获取数据,否则您可以完全放弃 useEffect 挂钩。

    这也解决了你的 second 问题,因为当你的组件第一次渲染时,钩子将运行一次,这由用作依赖数组的空数组 [] 指示useEffect 钩子。这相当于class-based 组件中的componentDidMount,但同样,此时调用credentialVerify 是没有意义的。

    至于您的第三个问题,您可能应该执行以下操作:

    const credentialVerify = event => {
      event.preventDefault();
    
      (async () => {
        const data = await fetch("http://localhost:5000/api/customers")
          .then(res => res.json());
          .catch(e => e);
        console.log(incomingData);
        // ...
      })();
    }
    

    由于您将异步函数作为事件处理程序传递,由于React 文档中所述的原因,您在访问 SyntheticEvent 对象时可能会遇到问题:

    SyntheticEvent 是池化的。这意味着 SyntheticEvent 对象将被重用,并且在调用事件回调后所有属性都将被取消。这是出于性能原因。因此,您不能以异步方式访问事件。


    您的最终组件应如下所示:

    function Signin() {
      const [name, setName] = useState("");
      const [password, setPassword] = useState("");
      const [items, setItems] = useState([]);
      const updateName = e => {
        setName(e.target.value);
      };
      const updatePassword = e => {
        setPassword(e.target.value);
      };
      const credentialVerify = event => {
        event.preventDefault();
    
        (async () => {
          const incomingdata = await fetch("http://localhost:5000/api/customers")
            .then(res => res.json())
            .catch(e => e);
          console.log(incomingdata);
          console.log(name, password);
          setItems(incomingdata);
        })();
      };
      return (
        <div>...</div>
      );
    }
    

    【讨论】:

    • @goti1 是的,现在这很有意义,现在代码也可以工作了。非常感谢:)
    猜你喜欢
    • 2013-08-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-03-17
    • 2015-07-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多