Heim  >  Fragen und Antworten  >  Hauptteil

Next.js: Serverkomponente aktualisieren, nachdem die Clientkomponente Daten geändert hat

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粉832212776P粉832212776381 Tage vor782

Antworte allen(2)Ich werde antworten

  • P粉904405941

    P粉9044059412023-10-27 13:25:50

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

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

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

    Antwort
    0
  • P粉345302753

    P粉3453027532023-10-27 12:33:01

    要将客户端组件更新的数据反映在服务器组件上,您可以使用 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' 的原因。

    Antwort
    0
  • StornierenAntwort