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

时间:2019-11-11 18:35:37

标签: javascript reactjs

我有一个数组,我必须从中添加/删除元素,而且由于使用了Set addhas,我认为我将使用delete来完成此操作

const [tags, setTags] = React.useState(new Set())

如果我想向tags添加一些内容,如何使用setTags做到这一点?还是我只打电话给tags.add()

4 个答案:

答案 0 :(得分:2)

我遵循以下方法,并且在我的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);
      setStateUseIds(userIds);
    } 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>)

}

希望这对具有相同用例的人有所帮助。 请参考以下Code Sandbox example

答案 1 :(得分:1)

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

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

添加元素

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

const addFoo = foo =>{
    setState(previousState => new Set([...state, foo]))
}

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

const addFoo = foo =>{
    setState(prev => new Set(prev.add(foo)))
}

删除元素

Removing有点棘手。首先,您需要将其转换成数组filter并传播结果

const removeFoo = foo =>{
    setState(prev => new Set([...prev].filter(x => x !== foo)))
}

要从上面更好地理解代码,可以像这样拆分它

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

答案 2 :(得分:1)

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

setTags(tags => new Set(tags).add(tag))

答案 3 :(得分:-2)

const [count, setCounter] = useState(0);
const [moreStuff, setMoreStuff] = useState();

const setCount = () => {
    setCounter(count + 1);
    setMoreStuff(...);

};