Is it possible to use ES6's Set
data structure in React?
For example, if I have a checklist composed of distinct items, and I'd like to maintain each item's checked state. I'd like to write something like this:
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... }
I understand there may be a problem with the fact that a Set is mutable by nature, and React performs a shallow comparison when updating the component, so it expects immutable objects to be passed and held in the state. However, is there a way to hold and maintain a Set object in the state?
You can use the hook like const set = useSetState([]) and then call set. add(el) , set. delete(el) etc..
render() Calling setState() here makes it possible for a component to produce infinite loops. The render() function should be pure, meaning that it does not modify a component's state. It returns the same result each time it's invoked, and it does not directly interact with the browser.
Changing the state Object When a value in the state object changes, the component will re-render, meaning that the output will change according to the new value(s).
You may call setState() immediately in componentDidMount() . It will trigger an extra rendering, but it will happen before the browser updates the screen.
Since react will identify state changes only if the state property was replaced, and not mutated (shallow compare), you'll have to create a new Set from the old one, and apply the changes to it.
This is possible since new Set(oldSet) !== oldSet
.
const oldSet = new Set([1, 2]); const newSet = new Set(oldSet); console.log(oldSet === newSet);
How you use a Set in a class component:
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... }
How to use a set with the useState()
hook:
const Comp = () => { [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 /* JSX */; }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With