调试React Hooks Rerender问题

时间:2019-02-19 23:48:28

标签: javascript reactjs react-hooks

我有一个非常简单的钩子,如下所示:

export const QuickViewCell = props => {
  const [hover, setHover] = useState(false)

  const handleMouseEvent = () => {
    console.log('calling')
    setHover(!hover)
  }

  console.log('hoverState', hover)

  return (
    <Box onMouseEnter={handleMouseEvent} onMouseLeave={handleMouseEvent}>
      <Text size="small">
        {String(props.data.name)} this is my custom cell and it is amazing
      </Text>
    </Box>
  )

当放置在项目的一个部分中时有效,但是当放置在另一部分中时则无效。就是说,handleMouseEvent函数总是被调用,但是组件不会以新状态重新渲染。 React和React-Dom在16.8.1。我没有任何错误。我不确定在哪里寻找错误。

如果我使用setState将其更改为类组件,则可以正常工作,这使我认为某个地方存在不兼容问题,但没有错误消息,也不知道在哪里查看。或者我缺少更明显的东西:)

有人遇到这样的事情吗?有没有办法确定是否与另一个软件包不兼容?

2 个答案:

答案 0 :(得分:1)

根据您问题中的以下措辞:

  

当放置在项目的一部分中时,它起作用,但当   放在另一个。

我假设这两个地方是同一建筑物的一部分(即相同的package.json)。如果真是这样,这似乎不太可能是不兼容的问题。但是以下是最近的评论:

  

此组件的代码在两种情况下都是相同的,主要是   不同的软件包。

听起来好像这两种情况是单独构建的一部分。如果这是真的,那么我认为钩子不兼容理论是合理的,尽管我并不完全相信,因为在这种情况下,我希望控制台中会显示一条消息(但是我怀疑多重反应副本有一些差异。不会导致控制台中出现消息的问题。

文档中的以下页面包含有关对此问题进行故障排除的说明:

https://reactjs.org/warnings/invalid-hook-call-warning.html#duplicate-react

在该页面上,您会找到以下说明,用于确定是否有多个版本的反应在起作用。

  

您可以在自己的计算机中运行npm ls react-domnpm ls react-native   应用程序文件夹以检查您使用的版本。如果你发现   不止其中之一,这可能还会造成问题(更多信息   下面)。

再往下走:

  

如果使用Node进行软件包管理,则可以在   项目文件夹:

     

npm ls react

如果这没有显示出任何意外(即,仅显示一份16.8.1的react和react-dom副本),那么我将继续假设不兼容的情况继续发展,并希望请参阅在有问题的情况下使用QuickViewCell的代码。

关于jayarjo关于使用“功能更新”语法的建议的切记,我认为更新此hover状态以更容易地知道其正确/健壮性的更适当方法是显式传递布尔值,而不是切换当前状态。

例如:

export const QuickViewCell = props => {
  const [hover, setHover] = useState(false)

  return (
    <Box onMouseEnter={()=>setHover(true)} onMouseLeave={()=>setHover(false)}>
      <Text size="small">
        {String(props.data.name)} this is my custom cell and it is amazing
      </Text>
    </Box>
  );
}

这使您更容易确信自己不会意外进入悬停状态,而悬停状态与实际情况相反。

答案 1 :(得分:0)

在使用前一个状态计算下一个状态时,建议使用functional updates

因此,请尝试使用setHover(!hover)而不是setHover(hover => !hover)。那应该做。