如何从孙组件LeftFilter向父组件UserList传值并更新DataGrid
从孙组件更新父组件状态的实现方案
针对你的组件树(UserList → DataGrid → FilterModal → LeftFilter),要实现孙组件LeftFilter的状态传递到父组件UserList并触发过滤操作,这里有两种直接可行的方案:
方案一:Props逐层传递(适合层级较少的场景)
这种方法通过逐层传递回调函数,让孙组件能触发父组件的状态更新逻辑,步骤如下:
- 父组件UserList:维护原始数据、过滤后数据的状态,并定义过滤处理函数,将函数和过滤后的数据向下传递
import { useState, useEffect } from 'react'; function UserList() { // 原始用户数据 const [originalUsers, setOriginalUsers] = useState([]); // 过滤后的用户数据 const [filteredUsers, setFilteredUsers] = useState([]); // 模拟获取原始数据 useEffect(() => { const mockUsers = [ { id: 1, name: '张三', age: 25 }, { id: 2, name: '李四', age: 30 }, { id: 3, name: '王五', age: 22 } ]; setOriginalUsers(mockUsers); setFilteredUsers(mockUsers); }, []); // 处理过滤参数变化的回调函数 const handleFilterChange = (filterParams) => { // 根据过滤参数执行过滤逻辑,示例按年龄范围过滤 let result = [...originalUsers]; if (filterParams.minAge) { result = result.filter(user => user.age >= filterParams.minAge); } if (filterParams.maxAge) { result = result.filter(user => user.age <= filterParams.maxAge); } setFilteredUsers(result); }; return ( <> {/* 将过滤处理函数和过滤后的数据传给DataGrid */} <DataGrid onFilterChange={handleFilterChange} data={filteredUsers} /> </> ); }
- 子组件DataGrid:接收父组件传递的回调函数,继续向下传给FilterModal
function DataGrid({ onFilterChange, data }) { // 渲染数据表格逻辑 return ( <> {/* 表格内容... */} {/* 将过滤回调函数传给FilterModal */} <FilterModal onFilterChange={onFilterChange} /> </> ); }
- 孙组件FilterModal:接收回调函数,继续传给LeftFilter
function FilterModal({ onFilterChange }) { // 弹窗结构逻辑 return ( <> {/* 弹窗内容... */} {/* 将过滤回调函数传给LeftFilter */} <LeftFilter onFilterChange={onFilterChange} /> </> ); }
- 曾孙组件LeftFilter:维护自身的过滤状态,变化时调用传递过来的回调函数
import { useState } from 'react'; function LeftFilter({ onFilterChange }) { // 维护LeftFilter自身的过滤参数状态 const [filterParams, setFilterParams] = useState({ minAge: '', maxAge: '' }); // 输入变化时更新本地状态,并触发父组件的过滤逻辑 const handleInputChange = (e) => { const { name, value } = e.target; const newParams = { ...filterParams, [name]: value ? Number(value) : '' }; setFilterParams(newParams); onFilterChange(newParams); }; return ( <> <div> <label>最小年龄:</label> <input type="number" name="minAge" value={filterParams.minAge} onChange={handleInputChange} /> </div> <div> <label>最大年龄:</label> <input type="number" name="maxAge" value={filterParams.maxAge} onChange={handleInputChange} /> </div> </> ); }
方案二:Context API(适合层级较深的场景)
如果后续组件层级可能继续加深,用Context可以避免逐层传递props的繁琐,步骤如下:
- 创建FilterContext
import { createContext, useContext, useState } from 'react'; // 创建过滤上下文 const FilterContext = createContext(); // 自定义Hook,方便子组件获取上下文 export function useFilter() { return useContext(FilterContext); } // 上下文Provider组件 export function FilterProvider({ children, originalData }) { const [filteredData, setFilteredData] = useState(originalData); const handleFilter = (filterParams) => { // 执行过滤逻辑 let result = [...originalData]; if (filterParams.minAge) { result = result.filter(user => user.age >= filterParams.minAge); } if (filterParams.maxAge) { result = result.filter(user => user.age <= filterParams.maxAge); } setFilteredData(result); }; return ( <FilterContext.Provider value={{ filteredData, handleFilter }}> {children} </FilterContext.Provider> ); }
- 父组件UserList:使用FilterProvider包裹子组件
import { useState, useEffect } from 'react'; import { FilterProvider } from './FilterContext'; function UserList() { const [originalUsers, setOriginalUsers] = useState([]); useEffect(() => { const mockUsers = [ { id: 1, name: '张三', age: 25 }, { id: 2, name: '李四', age: 30 }, { id: 3, name: '王五', age: 22 } ]; setOriginalUsers(mockUsers); }, []); return ( <FilterProvider originalData={originalUsers}> <DataGrid /> </FilterProvider> ); }
- 子组件DataGrid:直接通过useFilter获取过滤后的数据
import { useFilter } from './FilterContext'; function DataGrid() { const { filteredData } = useFilter(); // 渲染表格逻辑 return ( <> {/* 表格内容... */} <FilterModal /> </> ); }
- 孙组件FilterModal:无需传递props,直接渲染LeftFilter即可
function FilterModal() { // 弹窗结构逻辑 return ( <> {/* 弹窗内容... */} <LeftFilter /> </> ); }
- 曾孙组件LeftFilter:通过useFilter获取过滤函数并调用
import { useState } from 'react'; import { useFilter } from './FilterContext'; function LeftFilter() { const [filterParams, setFilterParams] = useState({ minAge: '', maxAge: '' }); const { handleFilter } = useFilter(); const handleInputChange = (e) => { const { name, value } = e.target; const newParams = { ...filterParams, [name]: value ? Number(value) : '' }; setFilterParams(newParams); handleFilter(newParams); }; return ( <> <div> <label>最小年龄:</label> <input type="number" name="minAge" value={filterParams.minAge} onChange={handleInputChange} /> </div> <div> <label>最大年龄:</label> <input type="number" name="maxAge" value={filterParams.maxAge} onChange={handleInputChange} /> </div> </> ); }
内容的提问来源于stack exchange,提问作者Ajay Bala
相关产品推荐
相关产品推荐

