【问题标题】:Ternary operator results in undefined useState after first render三元运算符在第一次渲染后导致未定义的 useState
【发布时间】:2021-07-30 07:34:40
【问题描述】:

我正在开发我的第一个 React.js 项目,并正在尝试构建个人网站的原始版本。我遇到了汉堡式侧边栏的下拉功能的问题 - 我想使用 onClick 显示和隐藏导航栏链接。我试图通过为我的导航栏(我的代码中的 .nav_links)提供一个 ID 来做到这一点,该 ID 将使用 showLinks 钩子并使用三元运算符从“隐藏”更改为“显示”。但是,div中三元运算符后的初始值在第一次渲染后设置为undefined,所以我的onClick方法不起作用。我希望能澄清这个问题,因为其他 stackoverflow 帖子似乎都与我编写网站的方法没有直接关系。

以下是我的部分代码供参考:

const [showLinks, setShowLinks] = useState(true);


    <nav>
        <ul className="nav_links" id={showLinks ? "hidden" : ""}>
            <li>Home</li>
            <li>About</li>
            <li>Projects</li>
            <li>Resume</li>
        </ul>
    </nav>
    <a className="contact_form" href="#"><button>Contact Me</button></a>
    <div className="burger" onClick={() => setShowLinks(!showLinks)}>
            <div className="line1"></div>
            <div className="line2"></div>
            <div className="line3"></div>
    </div>
</header>

我的部分 CSS:

@media screen and (max-width: 843px) {
    body {
        overflow-x: hidden;
    }

    .nav_links #hidden {
        display: none;
    }
    
    .nav_links {
        position: absolute;
        right: 0px;
        height: 20vh;
        top: 20vh;
        background-color: ghostwhite;
        display: flex;
        flex-direction: column;
        align-items: center;
        width: 100%;
        transition: transform 0.5s ease-in;
    }
}

【问题讨论】:

  • 这里.nav_links #hidden 隐藏了#hidden,它位于.nav_links
  • 我的想法是根据 showLinks 的设置来使用带有或不带有 #hidden 的 .nav_links。对我来说问题是第一行中的 id
  • 尝试将您的选择器更改为#hidden .nav_links,因为目前display: none 从未应用,因为#hidden 不在具有.nav_links 的元素内,无论showLinks 值如何。跨度>
  • 刚刚编辑它以通过 nav_links 获得 id,因为那是我目前在我的代码中所拥有的。还是不行。除了我的 .burger 类和行之外,我还有: onClick={console.log(document.getElementsByClassName("nav_links").id)} ,每次单击汉堡行时它都会打印 undefined 。
  • @EmilDimitrov 打败了我。在我输入答案时,他指出了选择器排序问题。 :)

标签: javascript html css reactjs


【解决方案1】:

像这样在ul标签前使用三元运算符

<nav>
    {(showLinks)?
    <ul className="nav_links" >
        <li>Home</li>
        <li>About</li>
        <li>Projects</li>
        <li>Resume</li>
    </ul>
    : null}
</nav>

【讨论】:

  • 你也可以这样做:&lt;nav&gt;{showLinks &amp;&amp; (&lt;ul&gt;...&lt;/ul&gt;)}&lt;/nav&gt;
【解决方案2】:

根据 W3C:

ID 和 NAME 标记必须以字母 ([A-Za-z]) 开头,并且可以是 后跟任意数量的字母、数字 ([0-9])、连字符 ("-")、 下划线(“_”)、冒号(“:”)和句点(“.”)。

属性的空白值无效。 在您的情况下,当您有 showLinksfalse 状态时,id 的值是 blank。这会导致一个未定义的值。

您可以使用className 代替id。但更好的方法是像这样有条件地渲染导航:

<nav>
    { 
      showLinks && <ul className="nav_links" id={showLinks ? "hidden" : ""}>
        <li>Home</li>
        <li>About</li>
        <li>Projects</li>
        <li>Resume</li>
      </ul>
    }
</nav>

【讨论】:

    【解决方案3】:

    我无法重现基于您的代码 sn-ps 描述的错误。

    这是一个可以运行的代码沙盒,其中包含您目前所拥有的内容:

    https://codesandbox.io/s/pensive-leaf-gm7pz

    我注意到的一个问题是您的#hidden 选择器的排序。你有这个:

    .nav_links #hidden {
      display: none;
    }
    

    但是,在您的标记中,您嵌套了这样的元素:

    <nav id="hidden">
      <ul className="nav_links">
      ...
    

    按原样,因为您切换了嵌套顺序,所以这不起作用。我将css更改为:

    #hidden .nav_links {
      display: none;
    }
    

    我还在Styles.css 中为您的.burger 类添加了占位符样式,以便在工作代码框示例中可见。

    结果(一旦用户将视口调整为移动宽度)会切换您的菜单状态,而不会出现任何控制台错误。如果没有更多上下文,不能说这正是您所追求的。如果它不能解决您的问题,我建议您尝试发布一个带有工作示例的更新代码框(同时保留它minimal),以便我们可以准确地看到失败的原因。


    旁注,我建议在您的 &lt;nav&gt; 元素上使用 class 而不是 id

    【讨论】:

      猜你喜欢
      • 2023-01-14
      • 2021-10-31
      • 1970-01-01
      • 2020-04-14
      • 1970-01-01
      • 1970-01-01
      • 2022-01-04
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多