React子组件向父组件传值:搜索组件与筛选抽屉联动问题
解决SuburbSearch与Filters组件的联动问题
看起来你卡在了React父子组件的状态同步上——子组件Filters里的筛选值没法传递到父组件SuburbSearch,导致没法用这些条件过滤搜索结果对吧?核心思路是状态提升:把筛选相关的状态放到父组件里,让子组件通过回调函数更新父组件的状态,这样父组件就能拿到实时的筛选条件来处理API结果了。
接下来一步步修改代码:
步骤1:在父组件SuburbSearch中添加筛选状态与回调函数
先在父组件里定义和子组件对应的筛选状态,以及更新这些状态的方法,同时把筛选逻辑和Autocomplete关联起来:
function SuburbSearch(props: Props) { const classes = useStyles(); const [value, setValue] = React.useState<App.Suburb | null>(null); const [inputValue, setInputValue] = React.useState(''); // 添加筛选状态,和子组件的字段一一对应 const [filterType, setFilterType] = React.useState<string | null>('all'); const [filterDollarRange, setFilterDollarRange] = useState<number[]>([0, 20000000]); // 给子组件的回调:更新类型筛选 const handleFilterTypeChange = (newType: string | null) => { setFilterType(newType); // 这里可以触发API重新请求,或者直接过滤现有options }; // 给子组件的回调:更新价格范围筛选 const handleFilterDollarChange = (newRange: number[]) => { setFilterDollarRange(newRange); // 同样触发API请求或本地过滤逻辑 }; // 自定义过滤函数,用筛选条件过滤结果 const customFilterOptions = (options: App.Suburb[]) => { return options.filter(suburb => { // 请根据你的实际数据结构调整字段名 const matchesType = filterType === 'all' || suburb.propertyType === filterType; const matchesPrice = suburb.price >= filterDollarRange[0] && suburb.price <= filterDollarRange[1]; return matchesType && matchesPrice; }); }; ... return ( <Autocomplete id="search" getOptionLabel={(option) => (typeof option === 'string' ? option : option.name + ' ' + option.state)} filterOptions={customFilterOptions} // 替换成带筛选逻辑的函数 options={options} ... renderInput={(params) => ( <TextField {...params} label="Search for a suburb" ..., startAdornment: ( <InputAdornment position="start"> {/* 把状态和回调传给Filters组件 */} <Filters currentType={filterType} currentDollarRange={filterDollarRange} onTypeChange={handleFilterTypeChange} onDollarChange={handleFilterDollarChange} ></Filters> </InputAdornment> ), endAdornment: ( <React.Fragment> {loading ? <CircularProgress color="inherit" size={20} /> : null} {params.InputProps.endAdornment} </React.Fragment> ), }} fullWidth /> )}
步骤2:修改Filters组件为受控组件
让Filters不再维护自己的筛选状态,而是使用父组件传递的状态和回调来同步更新:
// 先定义组件的props类型 interface FiltersProps { currentType: string | null; currentDollarRange: number[]; onTypeChange: (type: string | null) => void; onDollarChange: (range: number[]) => void; } export default function Filters(props: FiltersProps) { const classes = useStyles(); const [drawerOpen, setDrawerOpen] = useState(false); // 抽屉开关状态子组件可以自己维护 // 类型切换时调用父组件的回调 const handleTypeChange = (event: React.MouseEvent<HTMLElement>, newType: string | null) => { props.onTypeChange(newType); }; // 价格范围切换时调用父组件的回调 const handleDollarChange = (newRange: number[]) => { props.onDollarChange(newRange); }; const list = (anchor: Anchor) => ( <div className={classes.root} role="presentation" /*onClick={() => setDrawerOpen(false)} onKeyDown={() => setDrawerOpen(false)}/*/> <Grid className={classes.main} container spacing={2}> <Grid className={classes.row} item xs={1} md={2} /> <Grid className={classes.row} item xs={10} md={8}> <Typography className={classes.header} align='center' gutterBottom> Property Type </Typography> {/* 使用父组件传递的currentType作为选中值 */} <ToggleButtonGroup value={props.currentType} onChange={handleTypeChange} exclusive> <ToggleButton value="all" >All</ToggleButton> <ToggleButton value="some" >Some</ToggleButton> </ToggleButtonGroup> </Grid> {/* 价格范围组件同理,用props.currentDollarRange作为值,onChange调用handleDollarChange */} ... </Grid> </div> )}
核心逻辑说明
React的状态是单向流动的,子组件没法直接修改父组件的状态。通过状态提升,我们把需要共享的筛选状态放到父组件,子组件只负责渲染UI和触发回调,这样父组件就能实时拿到筛选条件,要么过滤现有选项,要么重新调用API获取符合条件的结果,实现父子组件的联动。
内容的提问来源于stack exchange,提问作者Steve M
相关产品推荐
相关产品推荐

