Cir*_*lus 5 javascript reactjs next.js next.js13
我无法理解 NextJS 13 中处理服务器端和客户端组件之间数据交换的正确方法。
我试图通过创建尽可能简单的场景来理解这一点。我有这两个函数可以简单地在服务器上读取和写入 JSON 文件:
import fs from 'fs'
export const saveData = async (data) => {
const jsonData = JSON.stringify(data)
try {
await fs.promises.writeFile('data/data.json', jsonData)
} catch (err) {
console.log('Error', err)
}
}
export const getData = async () => {
try {
const jsonData = await fs.promises.readFile('data/data.json')
const data = JSON.parse(jsonData)
return data
} catch (err) {
console.log('Error', err)
return null
}
}
Run Code Online (Sandbox Code Playgroud)
显示数据的 React 组件:
export const SomeComponent = ({ data }) => <p>{data.someKey}</p>
Run Code Online (Sandbox Code Playgroud)
以及一个获取用户输入的交互式 React 组件:
'use client'
import { useState } from 'react'
export default function Input({ handleInput }) {
const [value, setValue] = useState()
return (
<div>
<input type="text" onChange={(e) => setValue(e.target.value)}/>
<button onClick={() => handleInput(value)}>Save</button>
</div>
)
}
Run Code Online (Sandbox Code Playgroud)
如果我创建一个页面函数来获取数据并处理保存新数据,我无法将处理程序传递给输入组件,因为它是客户端组件。
import { SomeComponent } from './components/component'
import { getData, saveData } from './data'
import Input from './components/input'
export default async function Home() {
const data = await getData()
const handleInput = (data) => {
saveData(data)
}
return (
<div>
<SomeComponent data={data} />
{/* Error: */}
<Input handleInput={handleInput}/>
</div>
)
}
Run Code Online (Sandbox Code Playgroud)
那么,在这个例子中,客户端和服务器之间的数据传递应该如何处理呢?
谈到这个问题时,你基本上有两种选择:
选项 1:可以从客户端组件调用的 API,该组件更新文件并乐观地更新本地状态。可能是满足此类需求的更常见方法。
选项 2:与新挂钩结合传递到客户端组件的服务器操作useOptimistic。请记住,服务器操作仍处于 alpha 阶段,尚不建议在生产中使用。
我强烈建议您查看有关服务器操作的限制和规范的官方文档。这是一个简单的示例,如果实施,第二个选项可能会是什么样子:
const onSave = async (update: any) => {
"use server";
const { default: fs } = await import("fs");
await fs.writeJSON("./myfile.json", update);
}
async function ServerComponent(): Promise<JSX.Element> {
const data = await getMyData();
return <ClientComponent data={data} onSave={onSave} />;
}
Run Code Online (Sandbox Code Playgroud)
该use server指令用于将函数定义为服务器操作。请记住,服务器操作默认情况下不考虑会话,并且会为每个请求运行相同的函数。
function ClientComponent(props: Props): JSX.Element {
const { data: initialData, onSave } = props;
const [data, setData] = useState(initialData);
const onUpdate = useCallback(async (update: any) => {
setData(prev => ({ ...prev, ...update }));
await onSave(update);
}, [onSave]);
return // ...
}
Run Code Online (Sandbox Code Playgroud)
由于当前的 alpha 状态,您必须在下一个配置文件中激活服务器操作,否则此示例将无法工作。
| 归档时间: |
|
| 查看次数: |
3364 次 |
| 最近记录: |