【问题标题】:How to change in setState specific value in array of objects onClick event?如何更改对象数组中的 setState 特定值 onClick 事件?
【发布时间】:2021-11-17 16:31:15
【问题描述】:

我想在单击时更改我本地状态中的活动类并将 inActive 更改为该状态中的所有其他对象。

const [jobType, setJobType] = useState([
        {
            "class": "active",
            "type": "All Jobs"
        },
        {
            "class": "inActive",
            "type": "My Jobs"
        },
        {
            "class": "inActive",
            "type": "Saved Jobs"
        },
    ])

const jobTypeClick = (event, item) =>{
        alert("I am clicked")
        console.log(item)
        setJobType(...jobType, jobType.class:"active")
    }

const jobTypes = jobType.map((data) => {
        return (
            <p className={data.class+" mb-0 px-3 secondary-font fs-16"} key={data.type} onClick={event => jobTypeClick(event, data.type)}>{data.type}</p>
        )
    })

【问题讨论】:

标签: javascript reactjs json use-state


【解决方案1】:

此解决方案可行,但请记住 type 应该是唯一的

const jobTypeClick = (event, item) => {
    setJobType(jobType.map(t => {
        return { ...t, "class": (t.type === item) ? "active" : "inActive" }
    }))
}

否则,您可以将元素索引传递给函数,以确保您在 Array 中的唯一性。另一个不错的功能是将回调传递给set。回调将接收最新的值,允许您在异步逻辑中使用此函数。

const jobTypeClick = (event, index) => {
    setJobType(current => current.map((t, ix) => ({ ...t, "class": (ix === index) ? "active" : "inActive" }));
}

【讨论】:

  • 不要只是转储代码。说明您所做的更改以及进行更改的原因。
  • 太快了,我还在编辑;)
  • 您不必是第一个发帖者。下次花点时间写一个体面的深思熟虑的答案。
  • 谢谢,这对我来说非常有效,只是我身边的一个新手问题。为什么我们要映射?我们不能只使用之前的状态克隆设置状态并更改值吗?
  • 是的,但是您需要进行深层复制(复制数组以及元素)以防止更改先前状态中存在的元素。使用 Map 是因为我们想要一个新数组并且我们也在创建一个新对象(请参阅扩展操作 { ... t }
【解决方案2】:

你在 setJobType 中所做的是错误的 setJobType(...jobType, jobType.class:"active")
要设置JobType,您需要传递具有更新值的数组

您需要循环所有 jobTyes 并使类“inActive”到所有对象 并将具有相同点击索引的那个设置为“活动”

您可以使用以下代码 我添加了第三个参数来从 click 元素中读取索引 并循环所有 jobTypes 并将正确的一个设置为 active ,将另一个设置为 inActive

const [jobType, setJobType] = useState([
        {
            "class": "active",
            "type": "All Jobs"
        },
        {
            "class": "inActive",
            "type": "My Jobs"
        },
        {
            "class": "inActive",
            "type": "Saved Jobs"
        },
    ])

const jobTypeClick = (event, item, i ) =>{
        alert("I am clicked")
        console.log(item)
        let prevJobType = [...jobType];
        prevJobType.map((d,index) => {...d, class: index == i ? "active" : "inActive")
        setJobType(prevJobType)
    }

const jobTypes = jobType.map((data, i) => {
        return (
            <p className={data.class+" mb-0 px-3 secondary-font fs-16"} key={data.type} onClick={event => jobTypeClick(event, data.type, i)}>{data.type}</p>
        )
    })

【讨论】:

  • 不要只是转储代码。说明您所做的更改以及进行更改的原因。
  • 以下代码行 prevJobType.map(d =&gt; d.class = "inActive") 正在就地更改状态,因为 prevJobType 只是一个浅拷贝
  • 我已经添加了描述,谢谢@Andy
  • prevJobType 已经是一个副本。
  • @sojin 使用[...jobType] 只会使其成为浅拷贝,因此jobType 中的对象不会被复制,这意味着它们仍然指向与原始状态相同的对象引用,所以当你这样做时,你最终会修改原始状态。 d.class = "inActive"d 指的是原始状态的对象,因为它不是副本
猜你喜欢
  • 1970-01-01
  • 2021-06-24
  • 2020-10-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-03-26
相关资源
最近更新 更多