【问题标题】:Ternary Operator - Is there a possible bug in React's conditional rendering?三元运算符 - React 的条件渲染中是否存在可能的错误?
【发布时间】:2021-07-23 19:26:45
【问题描述】:

目前,我正在使用 Node.js 和 React 进行开发,遇到了一个奇怪的问题,我不确定我是否遗漏了某些内容,或者它是否是 React 的错误。

我想做的是使用三元运算符来呈现这样的条件HTML:

...
{
  missingTradingSystemNameError
  ?
    <div>
      ...
    </div>
  :
    duplicateTradingSystemNameError
    ?
      <div>
        ...
      </div>
    :
      null
}
...

这两个三元运算符条件都是我的 JSX.Element 函数中的状态变量。但是,这样做会导致以下形式的多个错误:

错误:

React Hook "React.useEffect" is called conditionally. React Hooks must be called in the exact same order in every component render

有趣的是,如果我添加第三个(无用的)嵌套条件来代替 null,那么一切都会按预期工作:

...
{
  missingTradingSystemNameError
  ?
    <div>
      ...
    </div>
  :
    duplicateTradingSystemNameError
    ?
      <div>
        ...
      </div>
    :
      <<condition3>>
      ?
        null
      :
        null
}
...

condition3 是第三个有状态变量,但正如您所见,附加条件没有任何作用,因此应该可以省略它。这是一个 React 错误还是我在这里遗漏了一些重要的东西?

(P.S.:请原谅我的代码不寻常的缩进,但对我来说,这是目前更复杂的 JSX 代码块最易读的解决方案)

编辑 1:

为了提供一些进一步要求的细节,这里是我简化的 useEffect() 代码块:

const [missingTradingSystemNameError, setMissingTradingSystemNameError] = React.useState(false);
const [duplicateTradingSystemNameError, setDuplicateTradingSystemNameError] = React.useState(false);

...

React.useEffect(() => {
    if (props.tradingSystemDialog && resetTradingSystemDialogOnNextOpen) {
      ...
      
      setMissingTradingSystemNameError(false);
      setDuplicateTradingSystemNameError(false);
      
      ...
    }
  }, [
    props.tradingSystemDialog,
    resetTradingSystemDialogOnNextOpen,
    tickFields,
    consolidatedFields
  ]);

missingTradingSystemNameError 是通过 setMissingTradingSystemNameError 设置的,duplicateTradingSystemNameError 是通过 setDuplicateTradingSystemNameError 设置的。如您所见,这些有状态变量可能在 useState() 中被更改,但它们不在 useState() 的依赖项中。

【问题讨论】:

  • 调用useEffect()的位在哪里?
  • 我刚刚在帖子中添加了有关我的 useEffect() 函数的其他信息。如果我能够创建一个最小的可复制示例,我将看看,但这可能很困难,因为代码直接连接到更复杂的功能。我可以想象这个问题在更简单的环境中不存在,但我会看看我能做些什么。
  • 每当你处理像 React 这样的大型库时,假设问题是你的,而不是库的。在这种情况下,使用嵌套的条件运算符是一种代码味道,您还没有足够抽象。
  • 是的,我可以想象问题就在我身边,但我现在看不到任何解决此问题的方法。在顶层,当使用像const [variable, setVariable] = React.useState(...); 这样的有状态变量时,将它们用作条件渲染的条件应该不多。我现在看不到与上述错误输出的联系(在所描述的情况下,这是由条件中使用的变量之外的其他状态变量引起的)。

标签: javascript node.js reactjs jsx conditional-operator


【解决方案1】:

提供一个最小的可重现示例是最好的,但在我的情况下上下文太复杂了。但是,我所做的是删除越来越多的代码来检查是否是一小部分导致了问题。现在我得出的结论是,文件中其他位置的以下代码 sn-p 是有问题的,并导致上述代码失败或至少以奇怪的方式表现:

...
{
  basicShortSettingsError
  ?
    <div className={classes.error}>
      <ErrorOutline
        className={classes.errorIcon}
      />
      <Typography className={classes.sectionError} variant="body2">
        {
          parseFloat(positionSizeShort) > parseFloat(maxContractsShort)
          ?
            "Position size > maximum contracts"
          :
            "Set position size and maximum contracts"
        }
      </Typography>
    </div>
  :
    null
}
...

由于某种原因,Typography 标记内的条件部分以前可以工作,但现在如果我在文件中的某个其他点通过我在问题中提到的内容扩展代码,则会导致错误。

为了澄清,这是导致问题的代码 sn-p:

<Typography className={classes.sectionError} variant="body2">
  {
    parseFloat(positionSizeShort) > parseFloat(maxContractsShort)
    ?
      "Position size > maximum contracts"
    :
      "Set position size and maximum contracts"
  }
</Typography>

positionSizeShortma​​xContractsShort 也是有状态的变量,我不知道为什么代码之前工作得很好,现在却失败了,但至少我找到了问题所在root 现在我可能可以做一个解决方法。

如果有人更清楚为什么这段代码有问题,非常欢迎在这里分享你的想法,因为我对我的问题没有真正的答案。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-10-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-11-27
    • 1970-01-01
    • 2021-06-30
    • 1970-01-01
    相关资源
    最近更新 更多