I am new to React js, and I am trying to create a contact list. Where you can add contacts, update, and delete contacts from your contact list. However, I am trying to initialize the state of my contact list but when I run it, it displays the contact list screen without the "initialState" of the contact list. Then when I try to add a contact it then throws a type error screen(state is not iterable). How do I fix this issue?
contactReducer.js:
const initialState = [
{ id: 0, name: "Raman Sharma", Level: " 20", Progress: "Master" },
{ id: 1, name: "Test Name", Level: " 25", Progress: "Master" },
];
export const contactReducer = (state = initialState , action) => {
switch (action.type) {
case "ADD_CONTACT":
state = [...state, action.payload];
return state;
case "DELETE_CONTACT":
const contactFilter = state.filter((contact) =>
contact.id === action.payload ? null : contact
);
state = contactFilter;
return state;
case "UPDATE_CONTACT":
const contactUpdate = state.filter((contact) =>
contact.id === action.payload.id
? Object.assign(contact, action.payload)
: contact
);
state = contactUpdate;
return state;
case "RESET_CONTACT":
state = [{ name: null, Level: null, Progress: null }];
return state;
default:
return state;
}
};
./client/AddContact/index.js
import React, { useState } from "react";
import { connect } from "react-redux";
import { useHistory } from "react-router";
import { toast } from "react-toastify";
const AddPost = ({ contacts, addContact }) => {
const [name, setName] = useState("");
// const [Level, setLevel] = useState("");
// const [Progress, setProgress] = useState("");
const history = useHistory();
const handleSubmit = (e) => {
e.preventDefault();
// const checkContactLevelExists = contacts.filter((contact) =>
// contact.Level === Level ? contact : null
//);
// const checkContactProgressExists = contacts.filter((contact) =>
// contact.Progress === Progress ? contact : null
//);
if ( !name) {
return toast.warning("Please fill in field!!");
}
// if (checkContactLevelExists.length > 0) {
// return toast.error("This Level already exists!!");
// }
// if (checkContactProgressExists.length > 0) {
// return toast.error("This Progress number already exists!!");
// }
const data = {
id: contacts.length > 0 ? contacts[contacts.length - 1].id + 1 : 0,
// Level,
name,
// Progress,
};
addContact(data);
toast.success("Player Added successfully!!");
history.push("/");
};
return (
<div className="container-fluid">
<h1 className="text-center text-dark py-3 display-2">Add Friend</h1>
<div className="row">
<div className="col-md-6 p-5 mx-auto shadow">
<form onSubmit={handleSubmit}>
<div className="form-group">
<input
className="form-control"
type="text"
placeholder="Full name"
value={name}
onChange={(e) => setName(e.target.value)}
/>
</div>
{/* <div className="form-group">
<input
className="form-control"
type="Level"
placeholder="Level"
value={Level}
onChange={(e) => setLevel(e.target.value)}
/>
</div> */}
{/* <div className="form-group">
<input
className="form-control"
type="number"
placeholder="Progress"
value={Progress}
onChange={(e) => setProgress(e.target.value)}
/>
</div> */}
<div className="form-group">
<input
className="btn btn-block btn-dark"
type="submit"
value="Add Student"
/>
</div>
</form>
</div>
</div>
</div>
);
};
const mapStateToProps = (state) => ({
contacts: state,
});
const mapDispatchToProps = (dispatch) => ({
addContact: (data) => {
dispatch({ type: "ADD_CONTACT", payload: data });
},
});
export default connect(mapStateToProps, mapDispatchToProps)(AddPost);
home.js
import React from "react";
import { connect } from "react-redux";
import { Link } from "react-router-dom";
const Friends = ({ contacts, deleteContact }) => {
return (
<div className="container">
<div className="row d-flex flex-column">
<Link to="/add" className="btn btn-outline-dark my-5 ml-auto ">
Add Friend
</Link>
<div className="col-md-10 mx-auto my-4">
<table className="table table-hover">
<thead className="table-header bg-dark text-white">
<tr>
<th scope="col">Id</th>
<th scope="col">Name</th>
<th scope="col">Level</th>
<th scope="col">Progess</th>
<th scope="col">Actions</th>
</tr>
</thead>
<tbody>
{contacts.length > 0 ? (
contacts.map((contact, id) => (
<tr key={id}>
<td>{id + 1}</td>
<td>{contact.name}</td>
<td>{contact.Level}</td>
<td>{contact.Progress}</td>
<td>
<Link
to={`/edit/${contact.id}`}
className="btn btn-sm btn-primary mr-1"
>
Edit
</Link>
<button
type="button"
onClick={() => deleteContact(contact.id)}
className="btn btn-sm btn-danger"
>
Remove
</button>
</td>
</tr>
))
) : (
<tr>
<th>No contacts found</th>
</tr>
)}
</tbody>
</table>
</div>
</div>
</div>
);
};
const mapStateToProps = (state) => ({
contacts: state,
});
const mapDispatchToProps = (dispatch) => ({
deleteContact: (id) => {
dispatch({ type: "DELETE_CONTACT", payload: id });
},
});
export default connect(mapStateToProps, mapDispatchToProps)(Friends);