我會盡量解釋你能理解這個問題的地方。
AddContact.js如果看到and中都有一個按鈕EditContact.js,例如Addbutton 和Updatebutton。它們被包裹起來<Link to="/"></Link>。但是,如果我單擊按鈕,則事件不會發生。如果我評論<Link>事件正在執行。我需要我的event handler并且<Link>應該作業。
如果您要評論或建議我在按鈕上放置一個事件處理程式,而不是onSubmit請您解釋為什么它是以及為什么它不能作為當前的代碼方式作業。
應用程式.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;
uj5u.com熱心網友回復:
我看到的問題是來自button元素的點擊事件傳播到Link組件,并且導航"/"有效地殺死了當前頁面/組件正在處理的任何內容。這意味著不呼叫form元素的處理程式。onSubmit
你有幾個選擇:
- 將
onClick事件處理程式添加到button并呼叫stopPropagationclick 事件物件,以防止它冒泡到Link. - 向組件添加
onClick事件處理程式Link并呼叫preventDefaultclick 事件物件。
在任何一種情況下,這里的目標都是防止立即導航發生,因此addandupdate處理程式將需要發出命令式重定向。
一個例子:
import { Link, useNavigate } from "react-router-dom";
const AddContact = ({ addContactAction }) => {
const navigate = useNavigate();
const [{ email, name }, setState] = React.useState({
name: "",
email: ""
});
const changeHandler = (e) => {
const { name, value } = e.target;
setState(state => ({
...state,
[name]: value,
}));
};
const add = (e) => {
e.preventDefault(); // <-- prevents default form action
if (name === "" || email === "") {
alert("Enter name and email!");
return;
}
addContactAction(state);
navigate("/", { replace: true }); // <-- navigate upon successful submit
};
return (
<div className="container">
<form onSubmit={add}>
<div className="row">
<div className="col-sm-12 mt-5">
<h2>Add Contact</h2>
</div>
<div className="col-sm-6">
<label htmlFor="name">Name</label>
<input
type="text"
id="name"
name="name"
className="form-control"
placeholder="name"
aria-label="name"
value={name}
onChange={changeHandler}
/>
</div>
<div className="col-sm-6">
<label htmlFor="email">Email</label>
<input
type="text"
id="email"
name="email"
className="form-control"
placeholder="email"
aria-label="email"
value={email}
onChange={changeHandler}
/>
</div>
<div className="col-sm-12 mt-3">
<Link
to="/"
onClick={e => e.preventDefault()} // <-- prevent default link action
>
<button className="btn btn-primary">Add</button>
</Link>
</div>
</div>
</form>
</div>
);
};
uj5u.com熱心網友回復:
關于:
如果您要評論或建議我在按鈕上而不是 onSubmit 上放置一個事件處理程式,您能否解釋一下為什么會這樣以及為什么它不能作為當前的代碼方式作業。
當事件冒泡時,有以下順序:
button onClick => Link onClick (navigation occurs) => form submit
當導航發生時,來自上一頁的 DOM 元素將與其事件偵聽器一起洗掉,并且不會呼叫 onSubmit。
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/505684.html
標籤:javascript 反应 重定向 反应路由器dom 反应链接
