javascript - 在 React 的状态中使用 Set 数据结构

标签 javascript reactjs set

是否可以在React中使用ES6的Set数据结构?

例如,如果我有一个由不同项目组成的 list ,并且我想维护每个项目的选中状态。我想写这样的东西:

export default class Checklist extends React.Component {
  constructor(props) {
    super(props);

    this.state = {
      checkedItems: new Set()
    }
  }

  addItem(item) {
    //...?
  }

  removeItem(item) {
    //...?
  }

  getItemCheckedStatus(item) {
    return this.state.checkedItems.has(item);
  }

  // More code...
}

我知道 Set 本质上是可变的,React 在更新组件时执行浅比较,因此它期望传递不可变对象(immutable对象)并将其保存在状态中,这一事实可能存在问题。但是,有没有办法在状态中保存并维护一个Set对象呢?

最佳答案

由于仅当状态属性被替换且未发生突变(浅比较)时,React 才会识别状态更改,因此您必须从旧集合创建一个新集合,并将更改应用于它。

这是可能的,因为new Set(oldSet) !== oldSet

const oldSet = new Set([1, 2]);
const newSet = new Set(oldSet);

console.log(oldSet === newSet);

<小时/>

如何在类组件中使用 Set:

export default class Checklist extends React.Component {
  constructor(props) {
    super(props);

    this.state = {
      checkedItems: new Set()
    }
    
    this.addItem = this.addItem.bind(this);
    this.removeItem = this.removeItem.bind(this);
  }

  addItem(item) {
    this.setState(({ checkedItems }) => ({
      checkedItems: new Set(checkedItems).add(item)
    }));
  }

  removeItem(item) {
    this.setState(({ checkedItems }) => {
      const newChecked = new Set(checkedItems);
      newChecked.delete(item);
      
      return {
       checkedItems: newChecked
      };
    });
  }

  getItemCheckedStatus(item) {
    return this.state.checkedItems.has(item);
  }

  // More code...
}
<小时/>

如何通过 useState() Hook 使用集合。

该示例添加 1-5 之间的随机整数,然后删除相同范围内的随机数。

const { useState } = React;

const Comp = () => {
  const [state, setState] = useState(() => new Set());

  const addItem = item => {
    setState(prev => new Set(prev).add(item));
  }

  const removeItem = item => {
    setState(prev => {
      const next = new Set(prev);

      next.delete(item);

      return next;
    });
  }

  return (
    <div>
      <button onClick={() => addItem(Math.ceil(Math.random() * 5))}>Add</button>
      <button onClick={() => removeItem(Math.ceil(Math.random() * 5))}>Remove</button>
      <div>
        {Array.from(state)}
      </div>
    </div>
  );
}

ReactDOM
  .createRoot(root)
  .render(<Comp />);
<script crossorigin src="https://unpkg.com/react@18/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@18/umd/react-dom.development.js"></script>

<div id="root"></div>

关于javascript - 在 React 的状态中使用 Set 数据结构,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44482788/

相关文章:

javascript - Alert.alert() 在 React Native 0.36.1 中不起作用

javascript - 将 "auto"宽度设置为计算值给出 0,但高度有效

javascript - 如何禁用 react 选择上的输入?

javascript - 使用 mapStateToProps Jest 测试 promise 函数

javascript - ReactJS 错误的组件被从 DOM 中删除

c++ - 如何打印包含集合的 map 内容?

javascript - 寻找有关 Javascript 测试框架的信息

algorithm - 固定大小的集合包含给定集合的最大数量

java - 集合什么时候允许重复?

javascript - 有效地听 JS .scroll()