Skip to content

Fixes a React race condition when using controlled inputs combined with server-side rendering

Notifications You must be signed in to change notification settings

chrisblossom/react-safe-universal-inputs

Repository files navigation

react-safe-universal-inputs

This module fixes a race condition when using controlled inputs combined with server-side rendering. If an input is changed before React is loaded, the change will not be registered.

Related issues: #2585 #4293

Demo: https://react-safe-universal-inputs.herokuapp.com

Usage:

yarn add react-safe-universal-inputs or npm install --save react-safe-universal-inputs

Optionally pass a function to onEarlyInput that handles a changed node, otherwise onChange is called.

Called once with componentDidMount and is only called if the value has changed before the initial react render.

import React, { Component } from 'react';
import { Input, Select } from 'react-safe-universal-inputs';

export default class Example extends Component {
    constructor() {
        super();
        
        this.state = {
            text: 'initial text',
            select: 'yes',
        };
        
        this.handleEarlyInput = this.handleEarlyInput.bind(this);
        this.handleChange = this.handleChange.bind(this);
    }
    
    handleEarlyInput(inputNode) {
        const value = inputNode.value;
        
        this.setState(() => {
            return {
                [inputNode.name]: value,
            }
        });
    }
    
    handleChange(event) {
        event.preventDefault();
        
        const type = event.target.type;
        const name = event.target.name;

        this.setState(() => {
            return {
                [name]: value,
            };
        });
    }
    
    render() {
        return (
            <form>
                <Input 
                    type="text"
                    name="text" 
                    onChange={this.handleChange} 
                    value={this.state.text}
                />
                
                <Select 
                    name="select" 
                    onEarlyInput={this.handleEarlyInput} 
                    onChange={this.handleChange} 
                    value={this.state.select}
                >
                    <option value="yes">yes</option>
                    <option value="no">no</option>
                </Select>
            </form>
        );
    }
}

See the /example/ folder / demo for more examples.

Known Issues:

  1. ref is not accessible.
  2. <textarea is not currently supported.

About

Fixes a React race condition when using controlled inputs combined with server-side rendering

Topics

Resources

Stars

Watchers

Forks

Packages

No packages published