【问题标题】:hide and show names using react hooks使用反应钩子隐藏和显示名称
【发布时间】:2019-12-29 04:41:17
【问题描述】:
  • 我是反应钩子的新手,
  • 最初在我的应用中,所有用户的名字都应该被隐藏。
  • 稍后当我单击每个用户时,它应该会显示名称。
  • 所以我使用了 show 和 setshow。
  • 当我试图在浏览器中打印值时,我没有看到它。return(<div>{show}users Data{setShow}
  • 我为每个用户写了点击,但我不知道如何隐藏和显示。
  • 我的应用中将有数百万用户,那么当我单击每个用户时隐藏和显示名称的最佳方式是什么
  • 在下面提供我的代码 sn-p 和沙箱

https://stackblitz.com/edit/react-t1mdfj?file=index.js

import React, { Component, useState } from "react";
import { render } from "react-dom";
import Hello from "./Hello";
import "./style.css";

function DataClick(){
  const [show, setShow]= useState(false);

  function showItem(e){
    console.log("e--->", e.target);
    setShow(true);
  }
  return(<div>{show}users Data{setShow}
  <div onClick= {showItem}
  //onClick={()=>setShow(true)}
    >user1</div>
    <div>John</div>
  <div onClick= {showItem}
  //onClick={()=>setShow(true)}
    >user2</div>
    <div>Mike</div>

    <div onClick= {showItem}
  //onClick={()=>setShow(true)}
    >user3</div>
    <div>Mike3</div><div onClick= {showItem}
  //onClick={()=>setShow(true)}
    >user4</div>
    <div>Mik4e</div><div onClick= {showItem}
  //onClick={()=>setShow(true)}
    >user5</div>
    <div>Mike5</div><div onClick= {showItem}
  //onClick={()=>setShow(true)}
    >user6</div>
    <div>Mike6</div><div onClick= {showItem}
  //onClick={()=>setShow(true)}
    >user7</div>
    <div>Mike7</div><div onClick= {showItem}
  //onClick={()=>setShow(true)}
    >user8</div>
    <div>Mike8</div>

  </div>);
}



render(<DataClick />, document.getElementById("root"));

【问题讨论】:

  • 使用 forEach 并遍历用户数量。
  • 你希望这条线做什么:return(&lt;div&gt;{show}users Data{setShow}?
  • 我以为在浏览器中它会显示为false users Data true。因为在顶部我们使用了这条线const [show, setShow]= useState(false);
  • @Tick20 你能在我的堆栈闪电战中更新吗,太令人困惑了:(
  • @computer 很酷,请查看我发布的答案。我也在你的 stackblitz 中更新了。

标签: javascript html css reactjs redux


【解决方案1】:

@computer 很酷,请参阅下面的实现,以在单击用户 id 时显示和隐藏用户名,这是@JMadelaine 实现的更新代码。希望这会有所帮助。 (在@JMadelaine 的实现中我发现的一个缺点是,一旦显示用户名,再次单击用户 ID 时它就不会隐藏起来,因为他总是将状态设置为 true onClick),请参阅下面的代码。

import React, { Component, useState } from "react";

const UserItem = ({ user }) => {
  const [isNameShown, setIsNameShown] = useState(false)

  const handleChange = () => {
    setIsNameShown(prevState => !prevState)
  }

  return (
    <div onClick={handleChange} >
      <div>{user.id}</div>
      {isNameShown && <div>{user.name}</div>}
    </div>
  )
}

function DataClick() {
  const users = [
    {
      id: 'user1',
      name: 'John',
    },
    {
      id: 'user2',
      name: 'Peter',
    },
  ]

  return (
    <div>
      {users.map(user => <UserItem user={user} />)}
    </div>
  )
}


export default DataClick;

这里的handleChange函数通过传递一个回调函数而不是直接值来使用之前的值设置状态的值,所以这个回调函数将获取之前的状态作为参数并返回反转的值,所以如果用户被打开,它会关闭,如果用户关闭它会打开。

编辑: 下面是代码setIsNameShown(prevState =&gt; !prevState)的解释

setIsNameShown 或 useState 钩子返回的任何函数都可以用以下方式编写。

第一种方式示例:

setIsNameShown(false)

在此,您直接传递要设置的值,而与之前的值无关。

第二种方式示例:

setIsNameShown((prevStateVariable) => {
    return !prevStateVariable
})

或者更简洁地可以写成

setIsNameShown(prevStateVariable =&gt; !prevStateVariable)

在这种情况下,函数 setIsNameShown 接受回调函数,该回调函数接收先前状态(与函数相关)作为参数。 因此,如果您需要将值设置为依赖于先前状态值的状态,请使用回调函数而不是直接提供值。

【讨论】:

  • 好吧,让我解释一下,函数 setIsNameShown 可以采用直接值或回调函数,如果您的值取决于前一个值,则始终首选使用回调函数。我将编辑我上面的代码并给出一个例子
  • 嘿,除了那一行,我们没有使用 prevStateVariable,仍然很困惑。可以举例说明吗
  • 嘿 @computer 很酷,变量 prevStateVariable 可以命名任何东西,这是一个作为第一个参数自动传递给具有先前状态的回调的参数。
  • @Tick20 我不认为 Computer Cool 理解 SO 的工作原理。看起来他正在准备面试,并希望我们教他 React。我已经调整了您的答案,以至少奖励您浪费的一些时间。如果您在您的答案中使用我的答案,如果您也可以投票给我,我将不胜感激。
  • @JMadelaine,我猜是一样的:)
【解决方案2】:

useState 钩子就像一个类组件的statesetState。在您的情况下,show 是具有truefalse 值的状态变量,您可以使用函数setShow 更改此值。

要有条件地显示用户名,您应该像这样使用show 的值:

return(
  <div>
    <div onClick={() => setShow(true)}>user1</div>
    {show && <div>John</div>}
    <div onClick={() => setShow(true)}>user2</div>
    {show && <div>Mike</div>}
  </div>
)

但是,我认为这不是您想要的。听起来你只想显示被点击的用户的名字,而在当前状态下,当你点击一个用户时,所有的用户名都会显示,因为它们都依赖于同一个状态变量show

您应该创建一个单独的组件,其中包含显示和隐藏用户名的逻辑,并将每个用户映射到该组件。这样,每个用户都有自己的show 状态。


编辑:

我已使用以下代码更新了您的代码:

// each user gets mapped to this component
const UserItem = ({user}) => {
  // that means each user has their own 'isNameShown' variable
  const [isNameShown, setIsNameShown] = useState(false)

  return (
    // if you click this div, this user's isNameShown value will be set to true
    <div onClick={() => setIsNameShown(true)}>
      // user.id is the id of the user from props
      <div>{user.id}</div>
      // only show this user's name if this user's isNameShown is true
      {isNameShown && <div>{user.name}</div>}
    </div>
  )
}

function DataClick(){

  // we just create some example users here for testing
  const users = [
    {
      id: 'user1',
      name: 'John',
    },
    {
      id: 'user2',
      name: 'Peter',
    },
  ]

  return(
    <div>
      // map each user to a UserItem, passing the user as a prop
      {users.map(user => <UserItem user={user} />)}
    </div>
  )
}

我不知道你的 users 数据结构是什么样的,所以你应该相应地改变它。

这里要学习的是,如果您发现自己一遍又一遍地重复代码或一遍又一遍地复制粘贴内容,那么通常有更好的方法来实现您想要的。您的用户列表基本上是一遍又一遍地复制和粘贴,因此您应该创建一个 UserItem 组件。

此代码可能存在问题,即一旦用户名可见,您就无法再次隐藏它,但如果这是您的意图,我会让您弄清楚如何做到这一点。

【讨论】:

  • 嘿,当我单击一个用户时,仅用户名就应该如此,您能否更新我的 stackblitz 如此混乱:(
  • 嘿,我需要更新 showItem 函数中的任何内容
  • 我已经更新了我的答案。你明白这里发生了什么以及为什么我创建了一个单独的UserItem 组件吗?
  • 嘿,我也需要把它隐藏起来 :( 你让代码 cmets 很难理解 :(
  • 我已经对我的代码进行了注释,你在哪个部分遇到了问题?
猜你喜欢
  • 2020-10-19
  • 2018-01-09
  • 2019-11-25
  • 1970-01-01
  • 2019-12-02
  • 2022-07-21
  • 2021-07-22
  • 2012-05-23
  • 1970-01-01
相关资源
最近更新 更多