NyaSol
NyaSol

Reputation: 567

How to properly Handle a state by user typing and timeout Reactjs

i have simple interactive app, and i want to render the CardList component, base on user search. the problem is i want to setTimeOut for the user search, and execute the function after 2000ms from when the user stoped typing.

here is the code, as you can see I managed to get it done, but its hacky and not really useful,im positive there is a better way to do this. what I'm doing right now is to always change this.state.robots arrry, acording to the user input. notice the searchBox component has an input field

class App extends Component {

    constructor(){
        super();
        this.state = {
            robots: robots,
            searchField: ''
        }
    }

    onSearchange = (event) =>{ 
        let timeOut = null;
        this.setState({searchField: event.target.value,robots:robots});

        event.target.onkeyup = (e) =>{
            clearTimeout(timeOut);
            timeOut = setTimeout(()=> {
                const  filterRobots = this.state.robots.filter(robot => {
                    return robot.name.toLowerCase().includes(this.state.searchField.toLowerCase());
                })
                this.setState({robots: filterRobots});
            },2000);

        }
    }

    render() {
        return (
            <div className = "tc">
                <h1>RoboFriend</h1>
                <SearchBox searchChange = {this.onSearchange}/> 
                <CardList robots = {this.state.robots} />
            </div>

        );
    }
}

I would like to be able to send fillterRobots array dynamically to the CardList component so i can render the results properly

Upvotes: 1

Views: 104

Answers (1)

Daniel Cottone
Daniel Cottone

Reputation: 4480

I would use something like lodash's debounce(). You don't just want a delay, you also want to cancel the previous delayed function execution if you receive a new event before the current delayed function has executed.

class TestComponent extends React.Component {
  constructor(props) {
    super(props);
    this.state = { value: '' };
    this.delayedCallback = _.debounce(this.handleChange, 1000);
  }

  handleChange(value) {
    this.setState({ value });
  }

  onChange(event) {
    event.persist();
    this.delayedCallback(event.target.value);
  }

  render() {
    return (
      <div>
        <input onChange={this.onChange.bind(this)} />
        <p>{this.state.value}</p>
      </div>
    );
  }
}

Upvotes: 2

Related Questions