我的第一个组件是一个服务器组件,其中包含我从数据库加载的项目列表。由于 seo,该列表应该在服务器端呈现。 我的第二个组件是一个包含输入字段的客户端组件。
当用户在输入字段中输入内容时,我想过滤与输入相关的项目列表。
我找不到在两个组件之间共享输入状态的方法,因此保存项目列表的组件可以是服务器组件。如果这是不可能的,有没有办法让它成为客户端组件,这样它仍然对搜索引擎优化友好?
对于此类问题可能会有一个非常通用的解决方案,但我从事nextjs开发时间不长,这是我第一次遇到它:/
我试图将问题分解到最小。
所以我有这个组件包含一个 inputField 和 outputField:
const SharedContextVariable = () => {
return (
<div className='w-full h-screen flex flex-col gap-5 justify-center items-center'>
<InputField />
<OutputField />
</div>
)
}
这是输入字段:
const InputField = () => {
const [input, setInput] = useState("");
return (
<input className='text-black p-2' placeholder='input' value={input} onChange={(e) => setInput(e.target.value)} />
)
}
这是输出字段:
const OutputField = () => {
return (
<div className='w-1/2 h-64 border-[1px] border-white flex justify-center items-center'>
<p className='text-white '>
{/* input should be displayed here */}
</p>
</div>
)
}
如何在outputField中实时显示inputField的输入,同时将其保留为服务器组件(如果可能的话)?
经过一番研究,我自己发现了。解决方案是使用基于 url 的 props。
这是扩展的示例代码,因此它具有预期的行为。
这是父组件(page.tsx):
import React from 'react'
import InputField from './components/inputField'
import OutputField from './components/outputField'
type Props = {
searchParams: { [key: string]: string | string[] | undefined },
}
const SharedState = (props: Props) => {
const searchParams = props.searchParams;
return (
<div className='w-full h-screen flex flex-col gap-5 justify-center
items-center'>
<InputField />
<OutputField searchParams={searchParams} />
</div>
)
}
export default SharedState
客户端组件(inputField.tsx):
'use client';
import React, { useState, useEffect } from 'react'
import { useDebounce } from 'use-debounce';
import { useRouter } from 'next/navigation';
const InputField = () => {
const [input, setInput] = useState("");
const [query] = useDebounce(input, 500);
const router = useRouter();
useEffect(() => {
if (!query) {
router.push('/sharedState');
}
else {
router.push(`/sharedState?query=${query}`)
}
}, [query]);
return (
<input
className='text-black p-2'
placeholder='...'
value={input}
onChange={(e) => setInput(e.target.value)}
/>
)
}
export default InputField
服务器组件(outputField.tsx):
type Props = {
searchParams: { [key: string]: string | string[] | undefined };
};
const OutputField = (props: Props) => {
const searchParams = props.searchParams;
const query = searchParams.query;
return (
<div className='w-1/2 h-64 border-[1px] border-white flex justify-
center items-center'>
<p className='text-white '>
{query}
</p>
</div>
)
}
export default OutputField