react-hooks 查询和 setState 导致 500 错误

react-hooks query and setState causes 500 error

我认为这可能是错误或配置错误。 我收到此错误: networkError: ServerError: Response not successful: Received status code 500

第一次提交表单我会得到想要的结果,但如果我再次点击提交按钮,我会收到上面的网络错误消息。

  const client = useApolloClient();
  const [val, setValu] = useState({
    email: 'example@example.com',
    password: 'password',
    texterror: {
      status: false,
      text: ''
    },
  })


//the submit function below: 

  const handleLogin = async (e) => {
    e.preventDefault();
    await client.query({
      query: Handle_Login, 
      variables: {
        email: val.email, 
        password: val.password
      }
    }).then((e) => {
      console.log(e)
    }).catch((e) => {
      setValu({
        texterror: {
          status: true, 
          text: 'it be broke yo'
        }
      })
    })
  }

但是,如果我在 catch 中删除 setValu({texterror: {status: true, text: 'it be broke yo'}}),500 错误就会消失。我可以向提交按钮发送垃圾邮件,但我不会收到 500 错误。

目前我不会在内部设置 setState 来避免这个问题,但我想知道这个问题是否有解决方案。

如有任何帮助,我们将不胜感激。提前致谢!

请记住,使用 useState 钩子会覆盖整个状态值。这意味着您不再有电子邮件和密码。从基于 class 的组件转移到挂钩时,这是一个常见的疏忽。添加状态中没有改变的部分,它应该会再次起作用。

在顶层,很明显您在服务器端造成了某种错误。 500 代码表示有 "internal server error"。所以你真的应该看看你的服务器代码并弄清楚如何防止意外输入,这样它就不会错误 and/or 崩溃而是 return 代码 400 即 "bad request".

所以问题就变成了,您的前端代码是如何导致格式错误的服务器请求的?

我怀疑您正在尝试使用 setValu()(这是一个 React 挂钩),就像在 class 组件中使用传统 setState 调用一样。但是,它们的行为却大不相同。

在 class 组件中,setState 执行旧状态和新状态的 "shallow merge"。所以如果你这样做了:

setState({
  texterror: {
    status: true, 
    text: 'it be broke yo'
  }
});

如果只在状态对象上找到字段 texterror 并更新它。

但是,React 钩子的工作方式不同。 useState() 创建单个原子值,当您调用 setValu() 时,它 complete 替换了先前存储在 val.

中的值

所以:

  const [val, setValu] = useState({
    email: 'example@example.com',
    password: 'password',
    texterror: {
      status: false,
      text: ''
    },
  });

  // val is now an object with 'email', 'password', and 'texterror' fields


  setValu({
    texterror: {
      status: true, 
      text: 'it be broke yo'
    }
  });

  // val is now an object with only a 'texterror' field

在您的代码中,当您使用 setValu 时,您将 val 的值完全替换为没有电子邮件或密码字段的内容,这在发送到服务器时会导致内部服务器错误。一个简单的修复方法是在更新时将 val 的旧值与所需的新对象简单地合并:

  setValu({
    ...val,
    texterror: {
      status: true, 
      text: 'it be broke yo'
    }
  });