How to filter array & update state when every click in React
Instead of updating items list in state on each filter change use state property to decide which items should be displayed during rendering.
State should always store whole list and you should just set state property indicating that completed
filter is active:
changeView(event) {
let clickStatus = event.target.value
this.setState({
completedFilter: clickStatus === 'completed' ? true : false
})
}
and then use this property to filter displayed items in render method:
render() {
let fileredItems = this.state.list;
if (this.state.completedFilter) {
fileredItems = this.state.list.filter((item) => item.completed);
}
return (
...
{
filteredItems.map((item) => {
//return item node
})
}
);
}
Admin
Updated on June 04, 2022Comments
-
Admin almost 2 years
I just wonder something about updating state in React. I'm working on basic "to-do app". I created a list & mapped for each element. The user can add a new element in the list and can change the status of the element.
Now, I want the state to update for every click. For example, when the user clicked the completed button, the state is called list will be contained only completed items. I can do it. But after I update the list, I can't access default list. For example, when the user click the button;
changeView(event) { let clickStatus = event.target.value if (clickStatus = 'completed') { const newList = this.state.list.filter((item) => { return item.completed }) this.setState({ this.state.list: newList }) }
But after this, I can't access the list that contains every item.
This is my code:
class App extends React.Component{ constructor(props) { super(props) this.state = { list: [ { 'text': 'First Item', 'completed': false }, { 'text': 'Second Item', 'completed': false }, { 'text': 'Third Item', 'completed': true } ] } this.handleStatus = this.handleStatus.bind(this) this.handleSubmit = this.handleSubmit.bind(this) } handleSubmit(event) { event.preventDefault() const newItem = { 'text': this.refs.new.value, 'completed': false } this.setState({ list: this.state.list.concat([newItem]) }) this.refs.new.value = '' } handleStatus(event) { const itemText = this.state.list[event.target.value].text const itemStatus = this.state.list[event.target.value].completed const newItem = { 'text': itemText, 'completed': itemStatus ? false : true } const list = this.state.list list[event.target.value] = newItem this.setState({ list }) } render() { const Item = this.state.list.map((item, index) => { return <li onClick={this.handleStatus} className={(item.completed) ? 'done' : 'default'} value={index} status={item.completed}>{item.text}</li> }) return ( <div> <form onSubmit={this.handleSubmit}> <input type='text' ref='new'></input> <button type='submit'>Add</button> </form> <ul> {Item} </ul> <div> <button value='all' type='submit'>All </button> <button value='completed' type='submit'>Completed </button> <button value='pending' type='submit'>Pending </button> </div> </div> ) } } ReactDOM.render(<App/>, document.getElementById('app'))