Next.js v13实时搜索栏问题:跨组件数据更新与结果过滤
解决方案:Next.js v13 实时搜索过滤实现
问题核心是搜索输入的状态仅存在于SearchBar组件内部,RobotList无法获取该值进行过滤。我们通过状态提升和组件间props传递来解决这个问题:
步骤1:将搜索状态提升到RootLayout
RootLayout是SearchBar和RobotList的共同父组件,把搜索状态放在这里可以让两个组件共享数据。修改layout.jsx:
'use client' import './globals.css'; import SearchBar from './SearchBar'; import { useState, cloneElement } from 'react'; export const metadata = { title: 'My App', description: 'Generated by create next app', } export default function RootLayout({ children }) { const [searchTerm, setSearchTerm] = useState(''); // 接收SearchBar传递的输入值,更新状态 const handleSearchChange = (value) => { setSearchTerm(value); }; // 给子组件(Home)传递searchTerm属性 const childrenWithProps = cloneElement(children, { searchTerm }); return ( <html lang="en"> <body className='text-center bg-sky-800'> <h1 className='text-4xl mt-4 text-white'>My App</h1> <SearchBar onSearchChange={handleSearchChange} /> {childrenWithProps} </body> </html> ) }
步骤2:修改SearchBar组件,传递输入值给父组件
让SearchBar通过props接收回调函数,把输入内容传递给RootLayout:
'use client' import { useState } from "react" export default function SearchBar({ onSearchChange }) { const [searchInput, setSearchInput] = useState(''); function handleChange(e) { const inputValue = e.target.value; setSearchInput(inputValue); // 调用父组件的回调,传递输入值 onSearchChange(inputValue); } return ( <input className="p-3 border rounded bg-blue-100" type="search" placeholder="Search Robots" value={searchInput} onChange={handleChange} /> ) }
步骤3:在Home组件中转递搜索关键词
修改page.jsx,接收RootLayout传递的searchTerm,并传递给RobotList:
import RobotList from './RobotList' export default function Home({ searchTerm }) { return ( <main> <RobotList searchTerm={searchTerm} /> </main> ) }
步骤4:在RobotList中实现过滤逻辑
接收searchTerm,根据关键词过滤机器人列表(支持名称和邮箱的模糊搜索,不区分大小写):
import Card from './Card' import { robots } from './robots' export default function RobotList({ searchTerm }) { // 过滤逻辑:匹配名称或邮箱包含搜索词 const filteredRobots = robots.filter(robot => { const lowerCaseTerm = searchTerm.toLowerCase(); return robot.name.toLowerCase().includes(lowerCaseTerm) || robot.email.toLowerCase().includes(lowerCaseTerm); }); return ( <main> {filteredRobots.map(robot => { return ( <Card key={robot.id} id={robot.id} name={robot.name} email={robot.email} /> ) }) } </main> ) }
这样修改后,输入框的内容变化会实时传递到RobotList,自动过滤并展示匹配的卡片。
内容的提问来源于stack exchange,提问作者Yusuf Saad
相关产品推荐
相关产品推荐

