【问题标题】:Conditional JSX renders despite condition not being met尽管条件未满足,但条件 JSX 仍会呈现
【发布时间】:2021-05-22 12:17:09
【问题描述】:

我有一个有条件渲染的组件。尽管不满足条件,但它似乎无论如何都在尝试渲染(我得到一个错误)。

一个简化的例子:

import { useState } from 'react';

const [state, setState] = useState(null)
console.log(state)
console.log(typeof state)

return (
  <div>
    {state && 
      <div>
        {state.map(element => <div>{element.title}</div>)}
      </div>
    }
  </div>
)

我收到错误消息:“无法读取 null 的属性 'map'”。我很确定state &amp;&amp; 之后的任何内容都不应该触发,所以我对发生的事情感到困惑。

如果可能,我想将null 作为我的状态的初始值(如果我提供一个空数组,这个错误就会消失)。

我已经尝试过各种情况,包括:

  • state !== null
  • typeOf state === 'object'
  • map 之前添加相同的state &amp;&amp; 条件

编辑:

console.log(state) 打印 nullconsole.log(typeof state) 打印 object; state 从未更新,nullobject 同时打印,因此有点令人困惑,尽管如此,这确定了问题的根源。

有人向我指出typeof null 确实是object

我正在使用处理jsx@emotion/react,所以问题可能源于那里。

【问题讨论】:

  • 我认为您的输入有误,缺少useState。但是,您确定您没有在组件的某处设置状态,或者有另一个可能导致该状态的同名变量吗?如果将其从 state 重命名为其他名称会发生​​什么?
  • 我只是仔细检查并没有在任何地方重复它(在我的示例中它只称为状态)。如果我提供一个空数组的初始值,该错误就会消失。
  • 这很有趣。当你控制台状态和它的类型时,你会得到什么?
  • > console.log(state) 打印 'null' 但 console.log(typeof state) 打印 'object'!因为null的类型是object
  • null 是一个object 类型,所以这是正确的developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…

标签: reactjs emotion


【解决方案1】:

您忘记发起useState

并且不要忘记从 react 顶部导入 useState 页面

import React,{useState} from 'react'; //from react
const [state, setState] = useState(null) // missing useState

【讨论】:

  • 抱歉造成混淆,但我只是忘记在我的示例中包含它;我的代码中存在具有初始值的 useState。
  • 这是一个有效的观点,但显然不是一个正确的答案。
【解决方案2】:

你必须在 useState 钩子中定义你的状态。

import React,{useState} from 'react';

const [state, setState] = useState(null)

【讨论】:

    【解决方案3】:

    您可能正在寻找这个:

    import { useState } from 'react';
    
    const [state, setState] = useState([])
    
    return (
      <div>
        {state.length > 0 && 
          <div>
            {state.map(element => <div>{element.title}</div>)}
          </div>
        }
      </div>
    )
    

    由于 JSX 声明性质,编译器引擎必须运行 state.map(...) 就像您放在大括号中的所有内容一样才能渲染 JSX,这就是发生运行时错误的原因,尽管不会渲染元素。为了避免这个错误,可以这样写{state &amp;&amp; state.map(element =&gt; &lt;div&gt;{element.title}&lt;/div&gt;)}

    【讨论】:

    • 正如我在帖子中提到的那样,这确实有效。 “从右到左执行所有代码,这就是发生运行时错误的原因”是什么意思?
    • 编译器引擎必须运行 state.map(...) 才能渲染 JSX。它是递归完成的,这就是我的意思。
    猜你喜欢
    • 1970-01-01
    • 2012-09-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-05-18
    • 1970-01-01
    • 2023-04-02
    • 1970-01-01
    相关资源
    最近更新 更多