如何将 Set 与 react 的 useState 一起使用?

a p*_*son 17 javascript reactjs

我有一个数组,我必须从中添加/删除元素,我想我会用它Set来完成这个,因为它的add hasdelete

const [tags, setTags] = React.useState(new Set())
Run Code Online (Sandbox Code Playgroud)

如果我想添加一些东西tags,我该怎么做setTags?或者我只是打电话tags.add()

Dup*_*cas 20

ASet根据定义是可变的,如果你只是调用,React 不会触发新的渲染,const newSet = set.add(0)因为以前和新之间的浅比较将始终断言为true

您可以使用spread运算符更改每次更新之间的引用,并仍然保持所有 Set 的行为

添加元素

const [state, setState] = useState(new Set())

const addFoo = foo =>{
    setState(previousState => new Set([...state, foo]))
}
Run Code Online (Sandbox Code Playgroud)

您仍然可以使用该add方法,因为它返回更新的集合

const addFoo = foo =>{
    setState(prev => new Set(prev.add(foo)))
}
Run Code Online (Sandbox Code Playgroud)

移除一个元素

Removing有点棘手。你首先需要把它变成一个数组,filter并传播结果

const removeFoo = foo =>{
    setState(prev => new Set([...prev].filter(x => x !== foo)))
}
Run Code Online (Sandbox Code Playgroud)

为了清楚起见

const removeFoo = foo =>{
    const arr = [...state].filter(x => x !== foo)
    setState(new Set(arr))
}
Run Code Online (Sandbox Code Playgroud)

  • 我建议保留前一个状态的完整性,如下所示: ```const addFoo = foo => setState(prev => (new Set(prev)).add(foo))``` 和 ```const removeFoo = foo => setState(prev => (new Set(prev)).delete(foo))``` (3认同)
  • @Dupocas,为什么在`removeFoo`中的`Set`内部传播/过滤?为什么不使用“删除”方法?`const removeFoo = foo => setState(prev => new Set([...prev.delete(foo)]));` (2认同)
  • 不确定上面的注释中是否使用了 `new Set(prev).delete(foo)` - `Set.add()` 的返回值是一个 Set,但 `Set.delete()` 的返回值是一个 Boolean 。 (2认同)

Jak*_*uby 11

你必须创建一个新的集合,否则 React 将不知道它需要重新渲染。像下面这样的东西会起作用。

setTags(tags => new Set(tags).add(tag))
Run Code Online (Sandbox Code Playgroud)


Pra*_*rma 10

我遵循以下方法,并且与我的 React Native 组件配合得很好。


const DummyComponent = () => {
const [stateUserIds, setStateUseIds] = useState(new Set());

....
....

const handleUserSelected = user => {
    // Since we cannot mutate the state value directly better to instantiate new state with the values of the state
    const userIds = new Set(stateUserIds);

    if (userIds.has(user.userId)) {
      userIds.delete(user.userId);
    } else {
      userIds.add(user.userId);
    }
    setStateUseIds(userIds);
  };

....
....


return (
   <View> 
       <FlatList
          data={dummyUsers}
          renderItem={({item, index}) => {
            const selected = stateUserIds.has(item.userId);
            return (
              
                <View style={{flex: 2}}>
                  <Switch
                    isSelected={selected}
                    toggleSwitch={() => handleUserSelected(item)}
                  />
                </View>
            );
          }}
          keyExtractor={(item, index) => item.userId.toString()}
        />
  </View>)

}

Run Code Online (Sandbox Code Playgroud)

希望这对具有相同用例的人有所帮助。请参考以下代码沙箱示例