How To Make My Code A Reusable Component?
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;
`
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
Related Questions
- → How do I create an array from a single form input box with php on octobercms?
- → Print the output value of an array in twig [OctoberCMS]
- → Declare an array variable to the controller/component [Laravel, October CMS]
- → Removing a JavaScript property inside a specific Object within an Array
- → Javascript loop indexing issue
- → search array without duplicates React.js
- → Populating array with items from different HTML attributes
- → Get all index value of 1 from binary "01000111"
- → Remove objects from array - Two different approaches, two different results when consulting the length of each array
- → Compare values in two arrays
- → adding multiple polygons in google maps using loops and arrays
- → .split() JS not "splitting" correctly?
- → Vue.js - Binding radio elements of same name to array