Search code examples
reactjsformsreact-functional-component

How to create a reusable input field using react?


I have InputField component which accepts various props like type,placeholder,value, etc. i am trying to create a form using InputField component. I can easily pass props from form but i cant save input values to my state. Here is my code.

InputField.js

import React, { useState } from "react";

const InputField = ({ value, label, placeholder, type, onChange }) => {
  const handleChange = (e) => {
    const { value } = e.target;
    onChange(value);
  };

  return (
    <div className="form-group">
      {label && <label htmlFor="input-field">{label}</label>}
      <input
        type={type}
        value={value}
        className="form-control"
        placeholder={placeholder}
        onChange={handleChange}
      />
    </div>
  );
};

export default InputField;

AddProductForm.js

import React, { useState } from "react";
import { Form, Button } from "reactstrap";
import InputField from "../UI/InputField";

const AddProductForm = () => {
  const [inputValue, setInputValue] = useState({ name: "", price: "" });
  const { name, price } = inputValue;

  const handleChange = (inputValue) => {
    setInputValue({ name: inputValue, price: inputValue });
    console.log(inputValue);
  };
  return (
    <Form>
      <InputField
        type="text"
        value={name}
        placeholder="Product Name"
        label="Name"
        onChange={handleChange}
      />
      <InputField
        type="number"
        value={price}
        placeholder="Add Price"
        label="Price"
        onChange={handleChange}
      />
      <Button color="primary">Add</Button>{" "}
      <Button color="secondary">Cancel</Button>
    </Form>
  );
};

export default AddProductForm;

Solution

  • Try passing from InputField event instead of value. Then in the handler you can take the input name and understand which field should be updated.

    Of course, by first adding name field for input as shown below:

    InputField.js

    import React  from "react";
    
    const InputField = ({ value, label, name, placeholder, type, onChange }) => (
      <div className="form-group">
        {label && <label htmlFor="input-field">{label}</label>}
        <input
          type={type}
          value={value}
          name={name}
          className="form-control"
          placeholder={placeholder}
          onChange={onChange}
        />
      </div>
    );
    
    export default InputField;
    

    AddProductForm.js

    import React, { useState } from "react";
    import InputField from "../UI/InputField";
    
    const AddProductForm = () => {
      const [inputValue, setInputValue] = useState({ name: "", price: "" });
      const { name, price } = inputValue;
    
      const handleChange = (e) => {
        const { name, value } = e.target;
        setInputValue((prev) => ({
          ...prev,
          [name]: value,
        }));
        console.log(inputValue);
      };
    
      return (
         <Form>
           <InputField
             type="text"
             value={name}
             placeholder="Product Name"
             label="Name"
             name="name"
             onChange={handleChange}
           />
           <InputField
             type="number"
             value={price}
             placeholder="Add Price"
             label="Price"
             name="price"
             onChange={handleChange}
           />
           <Button color="primary">Add</Button>{" "}
           <Button color="secondary">Cancel</Button>
         </Form>
      );
    };
    
    export default AddProductForm;