Next.js: Serverkomponente aktualisieren, nachdem die Clientkomponente Daten geändert hat
P粉832212776
P粉832212776 2023-10-26 17:59:27
0
2
843

Ich versuche immer noch, dieses Szenario zu verstehen. Kann jemand vorschlagen, wie dies in Next.js 13 richtig gemacht werden kann?

Ich zeige eine Liste von Benutzern in einer Serverkomponente an, zum Beispiel so (mit MongoDB):

// UsersList.jsx
const UsersList = () => {
  const users = await usersCollection.getUsers()

  return (
  <div>
    {users.map(user) => <div>{user}</div>}
  </div>
  )
}

Auf derselben Seite habe ich auch die Client-Komponente zum Hinzufügen von Benutzern definiert:

// UsersEdit.jsx
'use client'
const UsersEdit = () => {
  const handleAdd() => // calls POST to /api/users
  return // render input + button
}

Beide werden zusammen auf der Serverkomponentenseite angezeigt, wie unten gezeigt:

// page.jsx
const Users = () => {
  return (
  <div>
    <UsersList />
    <UsersEdit />
  </div>
  )
}

Wie soll ich „neu laden“ oder „benachrichtigen“ UsersList, dass ein neuer Benutzer zur Sammlung hinzugefügt wurde, um zu erzwingen, dass neue/aktualisierte Benutzer angezeigt werden?

P粉832212776
P粉832212776

Antworte allen(2)
P粉904405941

https://stackoverflow.com/a/75127011/17964403 这非常适合在客户端进行变异,但如果您想使用客户端的输入执行搜索/过滤之类的操作,并且想要重新获取相同的数据,您可以执行类似的操作

const [searchterm, setSearchterm] = useState("");
const handleSearch = (e) => {
   e.preventDefault();
   if(!searchterm)return
   router.push(/home?search=`${searchterm}`)
}

在服务器组件中,您将收到搜索参数作为道具,查看搜索参数是否存在,如果存在,则在 fetch 调用中传递该参数,您将获得过滤后的项目。

P粉345302753

要将客户端组件更新的数据反映在服务器组件上,您可以使用 router.refresh(),其中routeruseRouter()。以下是使用待办事项列表应用程序的示例:

// app/page.tsx

import Todo from "./todo";
async function getTodos() {
  const res = await fetch("https://api.example.com/todos", { cache: 'no-store' });
  const todos = await res.json();
  return todos;
}

export default async function Page() {
  const todos = await getTodos();
  return (
    <ul>
      {todos.map((todo) => (
        <Todo key={todo.id} {...todo} />
      ))}
    </ul>
  );
}
// app/todo.tsx

"use client";

import { useRouter } from 'next/navigation';
import { useState, useTransition } from 'react';

export default function Todo(todo) {
  const router = useRouter();
  const [isPending, startTransition] = useTransition();
  const [isFetching, setIsFetching] = useState(false);

  // Create inline loading UI
  const isMutating = isFetching || isPending;

  async function handleChange() {
    setIsFetching(true);
    // Mutate external data source
    await fetch(`https://api.example.com/todo/${todo.id}`, {
      method: 'PUT',
      body: JSON.stringify({ completed: !todo.completed }),
    });
    setIsFetching(false);

    startTransition(() => {
      // Refresh the current route and fetch new data from the server without
      // losing client-side browser or React state.
      router.refresh();
    });
  }

  return (
    <li style={{ opacity: !isMutating ? 1 : 0.7 }}>
      <input
        type="checkbox"
        checked={todo.completed}
        onChange={handleChange}
        disabled={isPending}
      />
      {todo.title}
    </li>
  );
}

⚠️:如果 抓取请求被缓存。这就是此示例中 cache: 'no-store' 的原因。

Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage