I will try to explain to the best where you can understand the issue.
If you see there is a button in both AddContact.js
and EditContact.js
, such as, Add
button and Update
button. They are wrapped by <Link to="/"></Link>
. However, if I click on the button the event is not happening. If I comment the <Link>
the event is being executed. I require both of my event handler
and <Link>
should work.
If you are going to comment or suggest me to put a event handler on button instead of onSubmit
could you please explain why it is and why not it will work being the present way of code.
App.js
import React, { useState, useEffect } from "react";
import { BrowserRouter as Router, Route, Routes, useNavigate, useLocation } from 'react-router-dom';
import { v4 as uuid } from 'uuid';
import api from "../api/contacts";
import './App.css';
import Header from './Header';
import AddContact from './AddContact';
import EditContact from "./EditContact";
import ContactList from './ContactList';
import ContactDetail from './ContactDetail';
function App() {
const [contacts, setContacts] = useState([]);
const [searchTerm, setSearchTerm] = useState("");
const [searchResults, setSearchResults] = useState("");
const [editContactDetail, setEditContactDetail] = useState("");
//Retrieve Contacts
const retrieveContacts = async () => {
const response = await api.get("contacts");
return response.data;
};
const addContactHandler = async (singleContact) => {
const addContact = {
id: uuid(),
...singleContact
};
const addContactDone = await api.post("/contacts", addContact);
setContacts([...contacts, addContactDone.data]);
};
const removeContactHandler = async (id) => {
await api.delete(`/contacts/${id}`);
const newContactList = contacts.filter((deleteContact) => {
return deleteContact.id !== id;
});
setContacts(newContactList);
};
const searchHandler = (searchTerm) => {
setSearchTerm(searchTerm);
if (searchTerm !== "") {
const newContactList = contacts.filter((contact) => {
return Object.values(contact)
.join(" ")
.toLowerCase()
.includes(searchTerm.toLowerCase());
});
setSearchResults(newContactList);
} else {
setSearchResults(contacts);
}
};
const editChosenContact = (id) => {
const newContactList = contacts.filter((editRecord) => {
return editRecord.id === id;
});
setEditContactDetail(newContactList);
};
const updateContactPerson = async (selectedContactEdit) => {
const editResponse = await api.put(`/contacts/${selectedContactEdit.id}`, selectedContactEdit);
const {id, name, email} = editResponse.data;
setContacts( contacts.map(contact => {
return contact.id === id ? {...editResponse.data} : contact;
})
);
};
useEffect(() => {
const getAllContacts = async () => {
const allContacts = await retrieveContacts();
if(allContacts) setContacts(allContacts);
}
getAllContacts();
}, []);
useEffect(() => {
console.log("useEffect happening!");
}, [contacts]);
return (
<div>
<Router>
<Header/>
<Routes>
<Route exact path="/" element={ <ContactList contacts={ searchTerm.length < 1 ? contacts : searchResults } getContactId={ removeContactHandler }
getEditContact={editChosenContact} term={ searchTerm } searchKeyword={ searchHandler } /> }/>
<Route exact path="/add" element={ <AddContact addContactAction={ addContactHandler } /> }/>
<Route exact path="/edit/:id" element={ <EditContact editContactPerson={ editContactDetail } updateContactPerson={ updateContactPerson } /> }/>
<Route exact path="/contact/:id" element={ <ContactDetail /> }/>
</Routes>
</Router>
</div>
);
}
export default App;
AddContact.js
import React from "react";
import { Link } from "react-router-dom";
class AddContact extends React.Component {
state = {
name: "",
email: ""
}
add = (e) => {
e.preventDefault();
if (this.state.name === "" || this.state.email === "") {
alert("Enter name and email!");
return;
}
this.props.addContactAction(this.state);
this.setState({ name: "", email: ""});
};
render() {
return (
<div className="container">
<form onSubmit={ this.add }>
<div className="row">
<div className="col-sm-12 mt-5">
<h2>Add Contact</h2>
</div>
<div className="col-sm-6">
<label for="name">Name</label>
<input type="text" id="name" className="form-control" placeholder="name" aria-label="name" value={this.state.name} onChange={ (e) => this.setState({name: e.target.value}) }/>
</div>
<div className="col-sm-6">
<label for="email">Email</label>
<input type="text" id="email" className="form-control" placeholder="email" aria-label="email" value={this.state.email } onChange={ (e) => this.setState({email: e.target.value}) }/>
</div>
<div className="col-sm-12 mt-3">
<Link to="/">
<button className="btn btn-primary">Add</button>
</Link>
</div>
</div>
</form>
</div>
);
}
}
export default AddContact;
EditContact.js
import React from "react";
import { Link, useLocation } from 'react-router-dom';
import ContactCard from "./ContactCard";
import ContactDetail from "./ContactDetail";
class EditContact extends React.Component {
constructor(props){
super(props);
this.state = {
id: props.editContactPerson[0].id,
name: props.editContactPerson[0].name,
email: props.editContactPerson[0].email
};
}
update = (e) => {
e.preventDefault();
if(this.state.name !== "" && this.state.email !== "") {
this.props.updateContactPerson(this.state);
} else {
alert("All fields are mandatory!");
}
};
render() {
return (
<div className="container">
<form onSubmit={ this.update }>
<div className="row">
<div className="col-sm-12 mt-5">
<h2>Edit Contact</h2>
</div>
<div className="col-sm-6">
<label for="name">Name</label>
<input type="text" id="name" className="form-control" placeholder="name" aria-label="name" value={this.state.name} onChange={ (e) => this.setState({name: e.target.value}) }/>
</div>
<div className="col-sm-6">
<label for="email">Email</label>
<input type="text" id="email" className="form-control" placeholder="email" aria-label="email" value={this.state.email } onChange={ (e) => this.setState({email: e.target.value}) }/>
</div>
<div className="col-sm-12 mt-3">
<Link to="/">
<button className="btn btn-primary">Update</button>
</Link>
</div>
</div>
</form>
</div>
);
}
}
export default EditContact;