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

Posted

技术标签:

【中文标题】react-hooks 查询和 setState 导致 500 错误【英文标题】:react-hooks query and setState causes 500 error 【发布时间】:2020-02-12 16:05:02 【问题描述】:

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

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

  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 以避免此问题,但我想知道是否有解决此问题的方法。

任何帮助将不胜感激。提前谢谢!

【问题讨论】:

当您说错误消失时,您的意思是它根本没有错误,即使在您的网络选项卡中也是如此?或者你的意思是它根本没有显示在你的状态? @TeeJ 抱歉,我应该更清楚一点。当我删除 catch 中的 setValu 并用普通的 console.log() 替换它时,没有 500 错误。如果我将 setValu 保留在 catch 中,则第一次提交成功,但如果再次按提交,则会收到 500 错误。 那是因为你没有用户名和密码。 console.log val 对两个请求进行确认,但这应该会有所帮助。 好的.......你是对的。我输入了 setValu( email: 'example@example.com', password: 'password', texterror: status: true, text: 'text' ) 并且有效。太感谢了!你应该把它作为一个答案,我会接受它。感谢您帮助我解决困扰我数小时的问题! 将其添加为任何未来读者的答案。很高兴我能提供帮助。 【参考方案1】:

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

【讨论】:

【参考方案2】:

在顶层,很明显您在服务器端造成了某种错误。 500 代码表示存在“内部服务器错误”。所以你真的应该看看你的服务器代码并弄清楚如何防止意外输入,这样它就不会出错和/或崩溃,而是返回代码400,这是“错误请求”。

那么问题就变成了,您的前端代码导致了格式错误的服务器请求怎么办?

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

在类组件中,setState 执行旧状态和新状态的“浅合并”。所以如果你这样做了:

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

如果只会在状态对象上找到字段 texterror 并对其进行更新。

但是,React 钩子的工作方式不同。 useState() 创建单个原子值,当您调用 setValu() 时,它完成替换之前存储在 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'
    
  );

【讨论】:

这完全有道理,非常感谢您的建议!

以上是关于react-hooks 查询和 setState 导致 500 错误的主要内容,如果未能解决你的问题,请参考以下文章

react-hooks

如何转换从@apollo/react-hooks 接收到的数据

停止中继:查询渲染器为某些 setStates 重新加载数据

为啥 setMouseDown(false) 不能联锁回调函数?

了解 react-hooks/exhaustive-deps useEffect 和调度事件

如何使用 React-Hooks 和 Apollo Client 在 React-GraphQL 中实现搜索功能?