代码之家  ›  专栏  ›  技术社区  ›  Rezi

NEXT JS无法从父组件(服务器)中的子组件(客户端)获取数据

  •  0
  • Rezi  · 技术社区  · 2 年前

    我有一个父组件,其中包含一个带有表单的子组件。我想从表单中获取数据并将其上传到数据库,但我不知道该怎么做。 这是我的子组件代码

    "use client"
    
    import React, { useState } from 'react';
    
    function AddProduct(func) {
        const [id, setId] = useState('');
        const [name, setName] = useState('');
    
        const handleIdChange = (e) => {
            setId(e.target.value);
        };
    
        const handleNameChange = (e) => {
            setName(e.target.value);
        };
    
        const handleSubmit = (e) => {
            e.preventDefault();
            console.log(`Product added: ID ${id}, Name ${name}`);
            func(id,name);
            //func(id,name);
            // Here you could send this data to your server or handle it some other way
        };
    
        return (
            <form onSubmith={handleSubmit} className=" card space-y-4">
                <div>
                    <label htmlFor="id" className="block text-sm font-medium text-gray-700">
                        ID
                    </label>
                    <input 
                        type="text"
                        id="id"
                        value={id}
                        onChange={handleIdChange}
                        className="mt-1 block w-full py-2 px-3 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm"
                    />
                </div>
                <div>
                    <label htmlFor="name" className="block text-sm font-medium text-gray-700">
                        Name
                    </label>
                    <input
                        type="text"
                        id="name"
                        value={name}
                        onChange={handleNameChange}
                        className="mt-1 block w-full py-2 px-3 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm"
                    />
                </div>
                <button type="submit" className="w-full py-2 px-4 border border-transparent rounded-md shadow-sm text-sm font-medium text-white bg-indigo-600 hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500">
                    Add Product
                </button>
            </form>
        );
    }
    
    export default AddProduct;
    
    
    

    这是父组件的代码

    "use server";
    
    import Sidebar from '@/components/Sidebar';
    import Link from 'next/link';
    import { redirect } from 'next/navigation';
    import SignOut from 'src/components/SignOut';
    import createClient from 'src/lib/supabase-server';
    import RootLayout from '../layout';
    import ProductsTable from '@/components/dashboardComponents/ProductsTable';
    import AddProduct from '@/components/dashboardComponents/AddProducts';
    
    export default async function Products() {
      const supabase = createClient();
      const {
        data: { user },
      } = await supabase.auth.getUser();
    
    
      let { data } = await supabase.from('products').select();
    
      async function func(id1,name1){
        "use server";
        console.log("started uploading data");
        console.log(id1);
        const { data, error } = await supabase
          .from('products')
          .insert([
            { id: id1, name: name1, customer_id: '1' },
          ])
          console.log("done uploading data");
          console.log(error);
    
    };
    
    
      return (
        <div>
        <ProductsTable data={data} ></ProductsTable>
        <AddProduct func={func()}></AddProduct>
        </div>
      );
    }
    
    

    这是在调用函数,但数据没有被传递,不确定还可以尝试什么,我尝试了道具钻孔,但它不起作用,因为useState不能在服务器上使用。这是创建全局道具的唯一方法吗?

    0 回复  |  直到 2 年前
        1
  •  0
  •   Habibur Rahman    2 年前

    请将函数引用作为道具而不是函数调用传递。

    父组件中的代码应该是这样的。

    return (
        <div>
        <AddProduct func={func}></AddProduct>
        </div>
      ); 
    
        2
  •  0
  •   Kannu Mandora    2 年前

    你不必使用 use server 东西。你只需要使用 API 你的电话 Client Component .

    试试这个:

    In client Component

        const handleSubmit = async (event) => {
         event.preventDefault();
         const request = await fetch("/api/dataEntry",{
         headers: {content-type: "application/json"},
         body: JSON.stringify({ id, name })
         method: "POST"
    });
         const response = await request.json();
         
         if(!response) return alert("Data is not entered")
         else{
         alert("Data Save Successfully");
    }
        };
    
    

    现在创建一个文件夹,路径为 app/api/dataEntry 并创建一个文件名 route.js/route.ts

    在里面 route.js/route.ts 文件

    export default function POST(request, response) {
     const {id, name} = await request.json();
     // Now you have your `id` and `name` on server.
    
    // Your can write your server code here which store the data into database.
    
    // but in the last you need to add this.
    
            return new Response(JSON.stringify("enter_your_data_which_you_need_to_return_on_client"), {
                headers: {
                    "content-type": "application/json; charset=UTF-8",
                },
            });
    
    }