Repository navigation
Delete a Contact
Now that we have learned how to create a new contact through the ContactCreate component,
we now need to learn how to delete it prior to editing it.
This step is pretty straightforward and will not require creating new routes.
Presentational components are components that are stateless and are not responsible for dealing with complex logic and lifecycle methods. Some call them 'dumb' components, since they just render something outright and nothing else.
Such components do not need to be class-based and inherit the Component class: we can declare
them as simple functions that return JSX. The main advantage of components like this is that they're
highly reusable: since they don't deal with any kind of logic, they can be rendered anywhere and
their functionality will not change.
Like we said earlier in the guide, we will place all stateless components in a components folder
to separate them from the stateful components stored in containers. The logic behind this naming
scheme is that the stateful components are, more often than not, higher-order components to stateless
components, therefore containing them, thus containers vs. components.
mkdir src/components
nano src/components/Button.jsimport React from 'react';
const Button = props => (
<button className={`btn ${props.buttonType}`} onClick={props.onClick} title={props.children}>
{props.children}
</button>
);
export default Button;When we're creating a stateless component as a function, the argument passed to it is the props object
that can be used in the same way as you would use this.props in a class-based, stateful component.
Now, let's render our new Button stateless component to the ContactList.
nano src/containers/ContactList.js...
import Button from '../components/Button';
...
<th> </th>
</tr>
</thead>
<tbody>
{
this.props.contactList.map(({ name, phone, email }, index) => (
<tr key={index}>
<td>{name}</td>
<td>{phone}</td>
<td>{email}</td>
<td>
<Button
buttonType="btn-danger"
onClick={() => this.props.onClickDelete(index)}
>
Delete
</Button>
</td>
</tr>
))
}
</tbody>
...Since we now need a function that manipulates our app state, we need to add it to mapDispatchToProps,
create a new action for it and wire up our reducer to understand the action and manipulate the state
accordingly.
Still in src/containers/ContactList.js:
...
import { contactDelete } from '../actions';
...
const mapDispatchToProps = dispatch => ({
onClickDelete: index => dispatch(contactDelete(index))
});
...We still haven't implemented contactDelete yet, so let's do it now:
nano src/actions/index.js...
export const contactDelete = index => ({
type: 'CONTACT_DELETE',
index
});And now we need contactsReducer to understand this new action:
nano src/reducers/contactsReducer.js...
case 'CONTACT_DELETE':
return {
...state,
contactList: [
...state.contactList.slice(0, action.index),
...state.contactList.slice(action.index + 1)
]
};
...Save, run yarn start and try adding contacts then deleting them.
git add .
git commit -m "Add feature to delete contacts"Next step: Edit a Contact