Ad

How To Make My Code A Reusable Component?

- 1 answer

Below is my code. I wanted to refactor this to make it a reusable component but don't know how to start. How can I do it? An answer is greatly appreciated. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Mauris auctor massa nisi, finibus rutrum ligula congue et. Nullam quam lacus, fringilla ac elit eu, scelerisque vulputate massa.

import React, { useState } from 'react';
import { Link } from 'react-router-dom';
import './styles.css';

const Commitment = () => {

    const [ fields, setFields ] = useState([{ value: "" }]);

    function handleChange(key, event) {
        const values = [...fields];
        values[key].value = event.target.value;
        setFields(values);
    }


    function handleAdd() {
        const values = [...fields];
        values.push({ value: "" });
        setFields(values);
    }

    function handleRemove(key) {
        const values = [...fields];
        values.splice(key, 1)
        setFields(values);
    }

    return (
        <div className="container">
            <div className="row">
                <div className="col-md-12 col-page">
                    <h1 className="page-heading">Create Your KLC</h1> 
                    <p>Make a commitment about something that you will commit to working on in this area:</p>
                </div>
                <div className="col-md-12"> 
                    <form id="form-commitment">
                        <div className="form-group">
                            <p className="form-label">My Commitment <i className="icon-help"></i></p>                       
                        </div>                      
                        {
                            fields.map((field, i) => {
                                return (
                                    <div key={`${field}-${i}`} className="form-group text-dynamic-inputs">
                                        <i className="icon-dynamic-inputs-counter">{i + 1}</i>
                                        <input 
                                            type="text" 
                                            className="form-control" 
                                            value={field.value}
                                            placeholder="Enter the text"
                                            onChange={e => handleChange(i, e)}
                                        />
                                        <button type="button" className="btn-remove" style={{ display: i === 0 && "none"}} onClick={() => handleRemove(i)}>
                                        </button>   
                                    </div>
                                );
                            })
                        }                                                                                       
                    </form>
                    <i className="icon-add-new"></i><Link to="#" onClick={() => handleAdd()} className="link-add-new">Add new</Link>  
                </div>
            </div>
        </div>                  
    )
}

export default Commitment;

`

Ad

Answer

Lets break your giant component into smaller dumb components first.

By looking at your code, Looks like page-heading , form-commitment, inside form, fields seems like can be a dump component and icon-add-new can be a dump component as well so let's separate them first and move code to appropriate components.

PageHeading

export const PageHeading= props => (
<div className="col-md-12 col-page">
    <h1 className="page-heading">Create Your KLC</h1> 
    <p>Make a commitment about something that you will commit to working on in this 
   area:</p>
  </div>
 );

Your FormCommitment component will look like this

export const FormCommitment = props => (
<div className="col-md-12">
<form id="form-commitment">
  <div className="form-group">
    <p className="form-label">
      My Commitment <i className="icon-help"></i>
    </p>

    {props.children()}
  </div>
</form>

);

and Field component like this

export const Field = props => (
<div className="form-group text-dynamic-inputs">
<i className="icon-dynamic-inputs-counter">{i + 1}</i>
<input
  type="text"
  className="form-control"
  value={props.field.value}
  placeholder="Enter the text"
  onChange={e => props.handleChange(i, e)}
/>
<button
  type="button"
  className="btn-remove"
  style={{ display: props.index === 0 && "none" }}
  onClick={() => props.handleRemove(i)}
   ></button>
  </div>
 );

Now comes smart component which look like this after refactoring

<Container>
<PageHeading />
<FormCommitment>
    {fields.map(field, index) => (
        <FormField 
            onChange= {handleChange} 
            onRemove= {handleRemove}  
            key={`${field}-${index}`} 
            index= {index}
            field= {field}
        />
    )}
  </FormCommitment>
  <AddNew  onChange = {handleAdd}/>
</Container>

Hope this would be helpful

Ad
source: stackoverflow.com
Ad