React Hook 在单击 2 个不同的按钮时从 APi 获取数据
Posted
技术标签:
【中文标题】React Hook 在单击 2 个不同的按钮时从 APi 获取数据【英文标题】:React Hook to fetch data from APi when click 2 different button 【发布时间】:2021-04-22 20:25:35 【问题描述】:我已经使用 mongoDB 作为数据库创建了 next.js 应用程序。
所以,我目前有 2 个按钮。 (删除,保存)。我希望我的应用程序在单击“删除”按钮时,它将使用fetch
使用 APi 从 mongoDB 中删除数据。其他,点击“保存”按钮,使用fetch
也可以使用API将数据保存到mongoDB。
首先,我使用document.getElementById('buttons').addEventListener('click', function (evt))
获取代码以将代码的字母部分执行到我想要的位置。
然后我使用 if-else 条件根据按钮的 id 在每个按钮上使用不同的 fetch
。
但是,每次我点击“保存”按钮时,它都会收到警报响应表单浏览器点击“确定”直到我之前点击保存的时间。例如,我点击“保存”按钮,输入数据为product_name
= car 和code
= 123,之后警报出现,我只需要点击一次“确定”。然后,我点击“保存”按钮,输入数据为product_name
= car 和code
= 124,之后出现警报,我必须点击两次“确定”。
“删除”按钮也是如此。
我该怎么办?
我在 react 应用的实际页面上的代码。
import Head from 'next/head'
import styles from '../styles/Home.module.css'
import 'bootstrap/dist/css/bootstrap.min.css'
import ButtonBar from '../components/buttonBar'
import InputGroup from 'react-bootstrap/InputGroup'
import FormControl from 'react-bootstrap/FormControl'
import BrandList from '../components/brandList'
import ModelList from '../components/modelList'
import Button from 'react-bootstrap/Button'
import ButtonGroup from 'react-bootstrap/ButtonGroup'
import connectToDatabase from "../util/mongodb"
import useForm from "react-hook-form";
export default function AddItem(item)
const register, handleSubmit, watch, errors = useForm();
const onSubmit = (data) =>
console.log(data)
document.getElementById('buttons').addEventListener('click', function(evt)
var target = evt.target;
if (target.id === 'add_item')
fetch('/api/item',
method: 'POST', // *GET, POST, PUT, DELETE, etc.
mode: 'cors', // no-cors, *cors, same-origin
cache: 'no-cache', // *default, no-cache, reload, force-cache, only-if-cached
credentials: 'same-origin', // include, *same-origin, omit
headers:
'Content-Type': 'application/json'// 'Content-Type': 'application/x-www-form-urlencoded',
,
redirect: 'follow', // manual, *follow, error
referrerPolicy: 'no-referrer', // no-referrer, *no-referrer-when-downgrade, origin, origin-when-cross-origin, same-origin, strict-origin, strict-origin-when-cross-origin, unsafe-url
body: JSON.stringify(data) // body data type must match "Content-Type" header
)
.then(response => response.json())
.then(data =>
console.log(data);
alert("Response from server " + data.message)
);
else if (target.id === 'del_item')
fetch('/api/item',
method: 'DELETE', // *GET, POST, PUT, DELETE, etc.
mode: 'cors', // no-cors, *cors, same-origin
cache: 'no-cache', // *default, no-cache, reload, force-cache, only-if-cached
credentials: 'same-origin', // include, *same-origin, omit
headers:
'Content-Type': 'application/json'
// 'Content-Type': 'application/x-www-form-urlencoded',
,
redirect: 'follow', // manual, *follow, error
referrerPolicy: 'no-referrer', // no-referrer, *no-referrer-when-downgrade, origin, origin-when-cross-origin, same-origin, strict-origin, strict-origin-when-cross-origin, unsafe-url
body: JSON.stringify(data) // body data type must match "Content-Type" header
)
.then(response => response.json())
.then(data =>
console.log(data);
alert("Response from server " + data.message)
);
, false); return (
<form onSubmit = handleSubmit(onSubmit)>
<Head >
<title> Add / Edit </title> <link rel = "icon" href = "/favicon.ico" / >
</Head>
<main className = styles.main>
<p className = styles.title>Add / Edit `</p>
Product Name: < input type = "text" name = "product_name" ref = register(required: true)/><br / >
Product Code: < input type = "text" name = "code"ref = register/><br / >
</main>
<div id = "buttons" >
<Button variant = "danger" type = "submit" value = "DELETE" id = "del_item"> Delete </Button' '
<Button type = "submit" value = "POST" id = "add_item" > Save < /Button>' '
<Button variant = "dark" > Back < /Button>' '
</div> <
/form>)
export async function getServerSideProps() const db = await connectToDatabase();
const item = await db
.collection("item")
.find()
.sort()
.limit(20)
.toArray();
return
props:
item: JSON.parse(JSON.stringify(item)),
,
;
我的 API:
import connectToDatabase from "../../util/mongodb";
export default async (req, res) =>
console.log("item API method " + req.method)
if (req.method === 'GET')
const db = await connectToDatabase();
const item = await db
.collection("item")
.find()
.sort()
.limit(20)
.toArray();
res.json(balance);
else if (req.method === 'POST')
console.log("item REQ", req.body)
let data = req.body;
let product_name, code, brand, model, avi_model, purchase_price, amount, limit_amount, barcode_id, date = data;
const db = await connectToDatabase();
let doc = await db
.collection('item')
.updateOne(
product_name: product_name,
code: code,
brand: brand,
model: model,
avi_model: avi_model,
purchase_price: purchase_price,
amount: amount,
limit_amount: limit_amount,
barcode_id: barcode_id,
date: date
,
$set: data ,
upsert: true
) // if update non-existing record, insert instead.
res.json( message: 'OK' );
else if (req.method === 'DELETE')
let data = req.body
let product_name = data;
const db = await connectToDatabase();
let doc = await db
.collection('item')
.deleteOne( product_name: product_name)
res.json(delete: true, message: 'Delete data', data: )
【问题讨论】:
【参考方案1】:您会触发多个警报,因为您在每次提交操作发生时(单击“保存”或“删除”时)添加一个事件侦听器。
要解决此问题,只需对代码进行最少的更改,您可以通过删除 addEventListener
并检查提交者 ID 来简单地更新 onSubmit
函数。
const onSubmit = (data, e) =>
console.log(data);
const submitterId = e.nativeEvent.submitter.id;
if (submitterId === 'add_item')
// Your `Add Item` logic here
else if (submitterId === 'del_item')
// Your `Delete Item` logic here
;
【讨论】:
“e”又是从哪里来的?如果“提交者”未定义?我需要导入任何东西吗? @faijiuy 抱歉,忘记添加那部分了。这是回调函数中的第二个参数:(data, e) =>
。我已经更新了我的答案。
至于submitter
是undefined
,这绝不应该发生,因为您必须有一个“提交者”才能触发提交操作。不过,如果你愿意,你可以防范它。以上是关于React Hook 在单击 2 个不同的按钮时从 APi 获取数据的主要内容,如果未能解决你的问题,请参考以下文章
如何在 React Native 中单击按钮时调用具有不同参数的相同 api