Nextjs 14 过滤表 - 服务器操作和水合

问题描述 投票:0回答:1

我有一张如下所示的表格。 enter image description here

可以通过单击编辑并更改其内容来编辑各个行。我现在需要的是:黄色的地方我需要过滤器。因此,当有人在姓氏中输入类似以下内容时:“Joh” 应显示与“Joh”匹配的所有条目。

简而言之,我的代码在应用程序中如下所示:

    /** page.js **/
    import connection from "/lib/db";
    import {format} from "date-fns";
    import Image from "next/image";
    import ClientTableRow from "@/components/ClientTableRow";

    export default async function Home() {
    /**
     * @type {{id: number, name: string, last_name: string, phone: string, email: string, 
    created_at: string}[]}
     */
    let data = [];
    try {
        const [rows] = await connection.query('SELECT * FROM clients');
        data = rows.map(row => ({
            ...row,
            created_at: format(new Date(row.created_at), 'dd-MM-yyyy HH:mm:ss')
        }));
    } catch (error) {
        console.error('Error fetching data:', error.message);
    }

    return (
      <table className="min-w-full divide-y divide-gray-300">
                                        <thead className="bg-gray-50">
                                        <tr>
                                            {/*filter should be here*/}
                                            <td>ID</td>
                                            <td>Name</td>
                                            <td>Last name</td>
                                            <td>Phone</td>
                                            <td>Email</td>
                                            <td>Created at</td>

                                            <td></td>
                                        </tr>
                                        </thead>
                                        <tbody className="divide-y divide-gray-200 bg-white">

                                        {data.map((item, index) => (
                                            <ClientTableRow key={index} client={item}/>
                                        ))}

                                        </tbody>
                                    </table>
    );

我还有一个 actions.js 和一个 ClientTableRow.js 文件。我认为不需要代码。

问题: 如何动态更新字段而不重新加载页面?我知道如何用纯前端 React 来做到这一点,我不知道如何用 nextjs 来处理这个问题。我假设通过部分补液和服务器操作可能有可能?

javascript reactjs next.js app-router nextjs14
1个回答
0
投票

您创建的是一个 React Server Page - 它允许异步调用,但不允许任何交互/动态脚本。相反,您必须将其设为 React 客户端页面。这是一个草图 - 过滤器有点不清楚,我认为超出了如何避免重新加载的问题范围。这是我大部分省略了过滤器方面的草图。

'use client'; // Now, this is not a React Server Component anymore
import connection from '/lib/db';
import { format } from 'date-fns';
import ClientTableRow from '@/components/ClientTableRow';
import { useEffect, useState } from 'react';

export default function Home() { // We cannot use async now, so I removed it
  const [selectedFilter, setSelectedFilter] = useState(); // no clue how filter looks like
  const [data, setData] = useState({});
  useEffect(() => {
    async function loadData() {
      const [rows] = await connection.query('SELECT * FROM clients');
      const data = rows.map(row => ({
        ...row,
        created_at: format(new Date(row.created_at), 'dd-MM-yyyy HH:mm:ss'),
      }));
      setData(data);
    }

    loadData(); // We're invoking this async method in a useEffect callback, which triggers a re-rendering when data gets changed
  }, [/* We load the data once, when rendering the first time */  ]);


  return (
    <table className="min-w-full divide-y divide-gray-300">
      <thead className="bg-gray-50">
      <tr>
        {/*filter should be here*/} 
        {/* TODO: add some kind of button logic here, which on click invokes setSelectedFilter with the clicked filter*/} 
        <td>ID</td>
        <td>Name</td>
        <td>Last name</td>
        <td>Phone</td>
        <td>Email</td>
        <td>Created at</td>

        <td></td>
      </tr>
      </thead>
      <tbody className="divide-y divide-gray-200 bg-white">

      {data.filter(d => true /*TODO check whether d matches the selectedFilter*/).map((item, index) => (
        <ClientTableRow key={index} client={item} />
      ))}

      </tbody>
    </table>
  )
};
© www.soinside.com 2019 - 2024. All rights reserved.