Handling User Input in React and Out of React

Nitish Kumar Singh

Feb 22, 2024

Hello developers! In this blog post, we will explore how we can handle user input in React and out of React, meaning the ways React provides to handle input and how we can write our own logic to handle user input in a better way than React.

Photo by Lautaro Andreani on Unsplash

Here, we will only discuss text inputs and handling input without adding input elements within a form element. To explore more about input handling in React go to its docs.

Handling User Input in React

React handles user input similarly to native input elements but with more control over user inputs. In React, we can handle user input as controlled input or simple input. What does controlled mean? It means that when a user enters some input, we first check that input and determine whether we want to accept that input or not.

To display an uncontrolled (simple) input element, we can simply add an input tag as shown in the code below and retrieve the user-entered input using the myInput reference.

<input ref={myInput} type="text"/>

This input element is considered as uncontrolled input by React until we add the value prop to it. After adding the value prop, React considers this input element as controlled and doesn't display any input entered by the user automatically.

When a user tries to enter any input, React prevents it and provides that entered input in the onChange event handler if provided. In onChange, we get that input by event.target.value and update the state to display that change as shown in the code below:

export default function Home() {
  const [value,setValue] = useState("");
  const change = (event)=>{
    const newValue = event.target.value;
    if (validate(newValue)) {
      setValue(newValue);
    }
  }
  return (
    <div>
      <input type="text" onChange={change} value={value}/>
    </div>
  )
}

Here, we have the chance to verify that input before displaying it to the user. But this can be problematic in some situations and/or provide a bad user experience.

Because in controlled input handling, input is not handled like a native element; instead, React provides the entered input without actually displaying it to the DOM, and when we change the state, it sets it to the element. Therefore, when a user tries to enter text at the beginning or anywhere except the end by moving the cursor (blinking line), the cursor automatically moves to the end, and this can be a bad user experience.

This is something we can solve by creating a custom React component.

Handling User Input out of React

We can handle user input with full control over inputs by creating a custom React component and writing logic code as required to validate and handle input. The code below is an example of that component:

import React, { Component, createRef } from 'react'

export default class EditText extends Component {
    ref = createRef(); 
    focus = ()=>{ 
        this.focued = true 
    }
    componentDidMount(){ 
        this.ref.current.value = this.props.value;
    }
    input = (event)=>{ 
        if(this.props.onChange) this.props.onChange(this.props.which, event.target.value);
    }
    blur = ()=>{  
        this.focued = false; 
        if(this.ref.current.value !== this.props.value) this.ref.current.value = this.props.value;
    }
    beforeInput = (event)=>{ 
        if (this.props.isRightInput && !this.props.isRightInput(this.props.which, event.data)) event.preventDefault();
    }
    render() {
        if(!this.focued && this.ref.current && this.ref.current.value !== this.props.value) this.ref.current.value = this.props.value; 
        return <input onBeforeInput={this.beforeInput} onChange={this.input} type={this.props.type} className={this.props.className} 
        style={this.props.style} ref={this.ref} onFocus={this.focus} onBlur={this.blur}/>
    }
}

This component handles input like the native way of the browser with our validation. In componentDidMount, it sets the provided value at first, and the first line of code in the render method is used for external rendering (when its parent re-renders).

This component can be used for any purpose of input handling with memorization of purpose using the which prop. It gives flexibility to enter input under validation (using isRightInput function) and set the last validated value on blur.

This component I have built to handle input of padding or margin like CSS strings. For example, if a user enters "10px 10", it automatically sets "10px" on blur because it is the last valid string for padding or margin.

You can customize it according to your requirements or build a new one that handles input outside of React. I hope this can help you. Happy Coding!

Published on Feb 22, 2024
Comments (undefined)

Read More