【问题标题】:Cleanly perform map() over Set collection state but still rerender on state changes?在 Set 集合状态上干净地执行 map() 但仍然在状态更改时重新渲染?
【发布时间】:2020-11-04 05:27:54
【问题描述】:

我有一组值。我想遍历这些并为每个值渲染一个组件。

我知道我不能使用forEach(),因为我需要返回一些东西,这就是为什么强烈推荐map()。 但我还是有一个Set不是一个Array

我可以使用Array.from(set) 但是当设置状态改变时它不再重新渲染,即使我很清楚状态确实已经改变了。

在一个状态下对 Set 集合的值进行 map() 的最简洁的方法是什么?

...

const [selected, setSelected] = useState(new Set([]))

const addToSelected = data => {
    setSelected(state => state.add(data))
    console.log(selected)
  }

render(
    {selected &&
      Array.from(selected).map(data => {
        return (
          <QuestionsItem
          key={data.message}
          data={data}
          negative
          callback={removeSelected}
          />
       )
    })}
)

【问题讨论】:

  • Array.from(set) 不会改变集合。我不明白为什么它应该对集合产生任何影响,包括任何侦听集合更改的重新渲染逻辑。使用Array.from 应该没问题——我猜还有其他事情发生。
  • @Christian 你能提供一些代码吗?你在使用一类功能组件吗?
  • @weltschmerz 据我了解,Array.from() 在第一次渲染时采用 set 的值,这意味着它并没有真正“监听”对 set 的更改,因此不会更新当设置发生变化时。
  • @Rostyslav 更新
  • JavaScript 中的 Set 是可变的,因此当您执行 state.add(data) 时,它会返回相同的 Set,并且 React 认为您的 selected 中没有任何变化,因为它仍然是相同的 Set。

标签: javascript reactjs data-structures


【解决方案1】:
  • JavaScript 集是可变的,这意味着您的 .add 调用不会改变 React 的基本 useState 能够注意到的任何内容;您的 selected 变量即使在您向其中添加内容时也保持不变

一个简单的方法是始终使用数组并自己检查重复值。这将不费吹灰之力:

const [selected, setSelected] = useState([])

const addToSelected = data => {
  if (selected.indexOf(data) === -1) {
    setSelected(state => [...state, data])
  }
  console.log(selected)
}

render(
    selected.map(data => {
      return (
        <QuestionsItem
        key={data.message}
        data={data}
        negative
        callback={removeSelected}
        />
      )
  })
)

【讨论】:

    猜你喜欢
    • 2018-02-27
    • 2023-01-28
    • 2018-11-29
    • 2017-11-16
    • 2020-04-24
    • 1970-01-01
    • 1970-01-01
    • 2020-06-26
    • 1970-01-01
    相关资源
    最近更新 更多