How to filter array & update state when every click in React

11,946

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
            })
        }
    );

}
Share:
11,946
Admin
Author by

Admin

Updated on June 04, 2022

Comments

  • Admin
    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'))