Learn How to create components, pass them data using props, and manage their data using state, by building a Contact Manager
Tags: javascript, react
Published: 2022-09-28 18:17:26

Our Contact Manager will allow us to view the list of contacts and add new ones to the list.


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ackzonrm42g2gcj4pqup.png)

By looking at the mockup, it makes sense to have two-component
**AddPersonForm:** a form with the text field and Add button.
**PeopleList:**a list of contacts

Let's create these components.
**AddPersonForm** uses the state to manage the value of the text field:

```
function AddPersonForm() {
  const [person, setPerson] = useState("");
}
function handleChange(e) {
setPerson(e.target.value);
}

function handleSubmit(e) {
e.preventDefault();
}
return (
<form onSubmit = {handleSubmit}>
<input type="text"
placeholder="Add new contact"
onChange={handleChange}
value={person} />
<button type="submit">Add</button>
</form>
);
}

```
For now, we just prevent the default behavior when the form is submitted.

**PeopleList** received an array representing the contacts and renders a list on the page:

```
function PeopleList(props) {
  const arr = props.data;
  const listItems = arr.map((val, index) =>
    <li Key={index}>{val}</li>
 );
return <ul>{listItems}</ul>;
}
```
Now we can render our components on the page and include some initial data:

```
const contacts = ["James Smith", "Thomas Anderson", "Bruce Wayne"];

const el = (
   <div>
     <AddPersonForm />
     <PeopleList data={contacts} />
   </div>
);
```

## **Sharing State**
Right now, our **AddPersonForm** independently keeps its state.
How can we add a new contact to our **PeopleList** when the form is submitted?

To accomplish that, we need to share the state between the components. We can do that by **lifting the state** to a parent component. This means that the parent component will hold the data that needs to be shared between the components. in our case, that is the contacts list.

Let's create a parent component called **ContactManager**, which includes the **AddPersonForm** and **PersonList** as child components, and hold the contacts list in its state:

```
function  ContactManager(props) {
  const [contacts, setContacts] = 
useState(props.data);

return (
  <div>
     <AddPersonForm />
     <PeopleList data={contacts} />
 </div>
);
}
```

## **Adding a Contact**
Now, we can create an addPerson() function to our ContactManager component to add a new person to our contacts state array:

```
function ContactManager(props) {
  const [contacts, setContacts] =
useState(props.data);

function addPerson(name) {
  setContacts([...contacts, name]);
 }
....
}
```
But how are we going to call this function from our child AddPersonForm component, where the data for the new person is stored?
Just like we passed down data using <u>props</u>, React allows us to pass down function references!

```
function ContactManager(props) {
  const [contacts, setContacts] =
useState(props.data);

function addPerson(name) {
  setContacts([...contacts, name]);
}

return (
<div>
<AddPersonForm handleSubmit={addPerson} />
<PeopleList data={contacts} />
</div>
);
}
```
Similar to passing the contacts list to our PeopleList component, 
we passed down the **addPerson()** function to our AddpersonForm using a prop called **handleSubmit**.

Now, our PeopleList can call the **handleSubmit** function that it received when the form is submitted, to add a new person to the list:

```
function AddPersonForm(props) {
  const [person, setPerson] = useState('');

  function handleChange(e) {
   setPerson(e.target.value);
 }
function handleSubmit(e) {
  props.handleSubmit(person);
 setPerson('');
e.preventDefault();
}
return (
     <form onSubmit={handleSubmit}>
     <input type="text"
       placeholder="Add new contact"
      onChange={handleChange}
     value={person} />
    <button type="submit">Add</button>
   </form>
);
}
```

## **Conclusion**
An important takeaway from this lesson is that **props** can be used to pass down not only the state but also functions, that may manipulate the state. 
This way, we can store the application state in the parent and allow its child components to use and manipulate the state.

Now, when our app is a full function, we can add some CSS styles and a check, to prevent the creation of blank contacts.