Heim > Fragen und Antworten > Hauptteil
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粉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 调用中传递该参数,您将获得过滤后的项目。
P粉3453027532023-10-27 12:33:01
要将客户端组件更新的数据反映在服务器组件上,您可以使用 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> ); }
⚠️:如果 抓取请求被缓存。这就是此示例中 cache: 'no-store'
的原因。