如何在 Nextjs 中的客户端组件和服务器组件之间共享状态变量?

问题描述 投票:0回答:1

我的第一个组件是一个服务器组件,其中包含我从数据库加载的项目列表。由于 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的输入,同时将其保留为服务器组件(如果可能的话)?

next.js state client react-context react-server-components
1个回答
0
投票

经过一番研究,我自己发现了。解决方案是使用基于 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
© www.soinside.com 2019 - 2024. All rights reserved.