Poohey
Poohey

Reputation: 21

What is the proper way to create reusable components react

Learning react and building a page where there is lots of input fields.
I want to create components for different input types so later i can use them instead of creating inputs over and over again.

I've wrote something like this but i repeat many things so i thought there might be a better way to do it.

class BaseInput extends React.Component {
  constructor(props) {
    super(props);
  }
  render() {
    return (
      <input
        id={this.props.id}
        name={this.props.name}
        type={this.props.type}
        value={this.props.value}
        onChange={this.props.onChange}
        placeholder={this.props.placeholder}
        required
      />
    );
  }
}

export function PasswordInput(props) {
  return (
    <BaseInput
      id={props.id}
      name={props.name}
      type="password"
      value={props.value}
      onChange={props.onChange}
      placeholder={props.placeholder}
    />
  );
}

export function TextInput(props) {
  return (
    <BaseInput
      id={props.id}
      name={props.name}
      type="text"
      value={props.value}
      onChange={props.onChange}
      placeholder={props.placeholder}
    />
  );
}

Upvotes: 1

Views: 1081

Answers (2)

SuleymanSah
SuleymanSah

Reputation: 17888

You can use spread operator to reduce code.

class TextInput extends React.Component {
  constructor(props) {
    super(props);
  }
  render() {
    return <input {...this.props} />;
  }
}

export default TextInput;

This way you even don't need a seperate PasswordInput component.

<TextInput id="name" type="text" placeholder="Your Name" />
<TextInput id="password" type="password" />

Upvotes: 3

Stefan Popovski
Stefan Popovski

Reputation: 516

Let's say your reusable component is named FormInput

The component definition should look like this:

const FormInput = (props: any) => {
  const [value, setValue] = useState(props.value);
  useEffect(() => {
    setValue(props.value);
  }, [props.value])

  return ( 
    <input
       autoComplete={props.autoComplete}
       name={props.name}
       type={props.type}
       id={props.id} 
       value={props.value}
       data-index={props.index} 
       onChange={props.onChange} 
       disabled={props.disabled}
       ariaLabelledBy={props.ariaLabelledBy} 
       required={props.required}/>
  )
};

And in the page where you want to use it you can simply invoke the component pass all the props to the component and implement the onChange event handler on the page:

Let's say you want to invoke the Input component on Login page:

const LoginPage = (props: any) => {
    ... // you have some useEffect etc. that is related to the business logic of the page

    const handleChange = (event: any) => {
      // put your logic here
    }

   return (
        ... // other HTML elements/components

       <FormInput type="text" onChange={handleChange} id="test" value="John Doe" ... />
   )
};

Upvotes: 1

Related Questions