Search code examples
javascriptreactjsreact-component

How to create a dynamic input type component


I'm developing a dynamic component where the input can be used for several types: text, password, number, date, etc. The idea is to use this input, no matter the type and where to implement it, as long its adaptable. I thought using state was a nice idea, but I have no clue how to do this. Any thoughts?

import React, { Component } from 'react';
import './styles.css';

export default class InputField extends Component {
constructor(props) {
    super(props);

    this.state = {
        name: '',
        password: false,
        type: ''
    }
}

render () {
    return (
        <div>
            <label className='f-size'>{this.state.name}</label>
            <input 
                className='input'
                name={this.state.name}
                placeholder={this.state.name}
                value={this.props.value}
                type={this.state.type}
                onChange={this.props.onChange}
            />
            <span className="errorMessage">{this.props.error}</span>
            <span className="errorMessage">{this.props.missField}</span>

        </div>

    )
}
}

Thank you!


Solution

  • I personally think you should control this via props, seeing as the value will only be meaningful to the Input's parent.

    I used this

    const InputField = ({
      name,
      placeholder,
      value,
      type,
      onChange,
      error,
      missField
    }) => (
      <div>
        <label className="f-size">{name}</label>
        <input
          className="input"
          name={name}
          placeholder={placeholder}
          value={value}
          type={type}
          onChange={onChange}
        />
        <span className="errorMessage">{error}</span>
        <span className="errorMessage">{missField}</span>
      </div>
    );
    

    Parent component:

    class App extends React.Component {
      constructor(props) {
        super(props);
    
        this.handleChange = this.handleChange.bind(this);
      }
      state = {
        value: '',
        password: '',
      };
    
      handleChange(event) {
        this.setState({ [event.target.name]: event.target.value });
      }
      render() {
        return (
          <div className="App">
            <InputField
              value={this.state.value}
              type="number"
              name="value"
              onChange={this.handleChange}
            />
            <InputField
              value={this.state.password}
              type="password"
              name="password"
              onChange={this.handleChange}
            />
          </div>
        );
      }
    }
    

    Code Sandbox: https://codesandbox.io/s/y4ljv75k9

    Edited to used a stateless component. Not sure if you want state to handle error messages but from your example, this is a valid solution.