Reputation: 119
I have custom list with custom methods. Trying to change list and call setState does not trigger component update
import React, {useState} from "react";
class MyCustomArray extends Array {
push(item) {
super.push(item);
return this;
}
}
export default () => {
const [items, setItems] = useState(new MyCustomArray());
console.log(items)
return (
<div>
{items.length}
<button onClick={() => setItems(items.push(1))}/>
</div>
);
}
I have tried same method using class component instead of function and it works.
import React, {Component} from "react";
class MyCustomArray extends Array {
push(item) {
super.push(item);
return this;
}
}
export default class App extends Component {
constructor(props) {
super(props);
this.state = {items: new MyCustomArray()};
}
render() {
const {items} = this.state;
return (
<div>
{items.length}
<button onClick={() => this.setState({items: items.push(1)})}/>
</div>
);
}
}
Upvotes: 1
Views: 78
Reputation: 17654
You need a new instance of items array, use the spread syntax,
import React, { useState } from "react";
class MyCustomArray extends Array {
push(item) {
super.push(item);
return this;
}
}
export default () => {
const [items, setItems] = useState(new MyCustomArray());
return (
<div>
{items.length}
<button onClick={() => setItems([...items, 1])} />
// ^^^^^^^^^^^^^
</div>
);
};
Same thing if you want to use a class
Component :
export default class App extends Component {
constructor(props) {
super(props);
this.state = { items: new MyCustomArray() };
}
updateItems = (item) => {
this.setState(prevState => ({
...prevState,
items: [...prevState.items, item]
}));
}
render() {
const { items } = this.state;
return (
<div>
{items.length}
<button onClick={() => this.updateItems(1)} />
</div>
);
}
}
Upvotes: 1