Search code examples
reactjsformsinputreact-reduxcontrolled-component

How to find when user stops typing in controlled components?


I am trying to capture the moment when the user stops typing in the controlled input. It happens so smooth inside the uncontrolled component.

When I have tried with setTimeout, only the last character came as an input rest all were not inputted. I am not sure why it happened

import React, { Component } from "react";
import ReactDOM from "react-dom";
import {connect} from 'react-redux';

import "./styles.css";

class Main extends Component{
  state={}

  timeout = null;

  onChange = e => {
    this.props.handleInputChange(e.target.value);
  }

  render(){
    return (
      <div className="Main">
        <input type='text' value={this.props.val} onChange={this.onChange}/>
      </div>
    );
  }
}

const mapStateToProps = state => {
  val: state.reducer.val
}

const mapDispatchToProps = dispatch => {
  handleInputChange: (val)=>dispatch(reducer.changeInput(val))
}

connect(mapStateToProps,mapDispatchToProps)(Main);

when User stops typing, it should dispatch changeInput action


Solution

  • You can do that with something like this:

    
    const App = () => {
      const [value, setValue] = React.useState('')
    
      React.useEffect(() => {
        const timeout = setTimeout(() => {
          store.dispatch({ type: "CHANGE_INPUT", val: value });
        }, 2000)
    
        // if this effect run again, because `value` changed, we remove the previous timeout
        return () => clearTimeout(timeout)
      }, [value])
    
      return (
        <input
          type="text"
          value={value}
          onChange={(e) => setValue(e.target.value)}
        />
      )
    }
    

    Everytime the value state change, the useEffect function will run. A timeout will start, that can be cancelled if the value change again before the setTimeout function is executed ( after 2 seconds in my example ).