Next.js:客戶端元件修改資料後更新伺服器元件
P粉832212776
P粉832212776 2023-10-26 17:59:27
0
2
797

我仍在嘗試理解這個場景。誰能建議在 Next.js 13 中執行此操作的正確方法是什麼?

我在伺服器元件中顯示使用者列表,例如,如下所示(使用 MongoDB):

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

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

在同一頁上,我還定義了用於新增使用者的客戶端元件:

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

兩者在伺服器元件頁面中一起顯示,如下所示:

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

我應該如何「重新載入」或「通知」UsersList新使用者已新增至集合中以強制其顯示新使用者/更新的使用者?

P粉832212776
P粉832212776

全部回覆(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(),其中router useRouter()。以下是使用待辦事項清單應用程式的範例:

// 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>
  );
}

⚠️:如果refresh() 可能會重新產生相同的結果快取” rel="nofollow noreferrer">抓取請求被快取。這就是這個範例中 cache: 'no-store' 的原因。

熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板