【问题标题】:React Hook to fetch data from APi when click 2 different buttonReact Hook 在单击 2 个不同的按钮时从 APi 获取数据
【发布时间】: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: {}})
   }}

【问题讨论】:

    标签: javascript reactjs mongodb api next.js


    【解决方案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) =&gt; {}。我已经更新了我的答案。
    • 至于submitterundefined,这绝不应该发生,因为您必须有一个“提交者”才能触发提交操作。不过,如果你愿意,你可以防范它。
    猜你喜欢
    • 1970-01-01
    • 2022-01-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-11-30
    • 2020-05-15
    • 2017-07-01
    • 2019-06-16
    相关资源
    最近更新 更多