如何在React父组件中获取子组件SortSelect的sortType状态
实现方案
核心思路采用React官方推荐的状态提升方案,将子组件内部的sortType状态移到父组件Home中维护,子组件通过props接收状态值和修改状态的回调函数,即可实现父组件实时获取排序类型的需求。
步骤1:改造SortSelect子组件
删除子组件内部的sortType状态,改为通过props接收参数:
export default function SortSelect({ sortType, onSortChange }) { const classes = useStyles(); const handleChange = (event) => { // 将最新的排序类型传递给父组件 onSortChange(event.target.value); }; return ( <FormControl className={classes.formControl}> <Select value={sortType} onChange={handleChange} displayEmpty className={classes.selectEmpty} inputProps={{ 'aria-label': 'Without label' }} > <MenuItem value='asc'>Count asc</MenuItem> <MenuItem value='desc'>Count desc</MenuItem> <MenuItem value='a-z'>Name A-Z</MenuItem> <MenuItem value='z-a'>Name Z-A</MenuItem> </Select> <FormHelperText>Sort by</FormHelperText> </FormControl> ); }
步骤2:在Home父组件中维护状态并实现排序逻辑
在父组件中定义sortType状态,传递给子组件,同时基于该状态实现数组排序:
import { useState } from 'react'; import SortSelect from './SortSelect'; // 替换为你实际的组件导入路径 export default function Home() { // 父组件统一维护排序类型状态 const [sortType, setSortType] = useState('asc'); // 示例待排序数组,替换为你的实际业务数据 const [dataList, setDataList] = useState([ { name: '苹果', count: 12 }, { name: '香蕉', count: 7 }, { name: '橙子', count: 22 } ]); // 根据sortType生成排序后的数组 const sortedList = [...dataList].sort((a, b) => { switch(sortType) { case 'asc': return a.count - b.count; case 'desc': return b.count - a.count; case 'a-z': return a.name.localeCompare(b.name); case 'z-a': return b.name.localeCompare(a.name); default: return 0; } }); return ( <div> {/* 将状态和修改回调传递给子组件 */} <SortSelect sortType={sortType} onSortChange={setSortType} /> {/* 渲染排序后的数组 */} {sortedList.map(item => ( <div key={item.name}>{item.name} - 库存:{item.count}</div> ))} </div> ) }
可选方案:通过ref暴露子组件状态(不推荐,仅特殊场景使用)
如果你的场景不适合把状态提升到父组件,可以通过useImperativeHandle + forwardRef的方式主动获取子组件的状态,缺点是无法自动监听状态变化,需要手动触发获取:
子组件改造
import { forwardRef, useImperativeHandle, useState } from 'react'; const SortSelect = forwardRef((props, ref) => { const classes = useStyles(); const [sortType, setSortType] = useState('asc'); const handleChange = (event) => { setSortType(event.target.value); }; // 暴露给父组件可调用的方法 useImperativeHandle(ref, () => ({ getCurrentSortType: () => sortType })); return ( <FormControl className={classes.formControl}> <Select value={sortType} onChange={handleChange} displayEmpty className={classes.selectEmpty} inputProps={{ 'aria-label': 'Without label' }} > <MenuItem value='asc'>Count asc</MenuItem> <MenuItem value='desc'>Count desc</MenuItem> <MenuItem value='a-z'>Name A-Z</MenuItem> <MenuItem value='z-a'>Name Z-A</MenuItem> </Select> <FormHelperText>Sort by</FormHelperText> </FormControl> ); }); export default SortSelect;
父组件使用
import { useRef } from 'react'; import SortSelect from './SortSelect'; export default function Home() { const sortSelectRef = useRef(null); const handleSort = () => { const currentSort = sortSelectRef.current?.getCurrentSortType(); // 拿到currentSort后执行排序逻辑 } return <div> <SortSelect ref={sortSelectRef} /> <button onClick={handleSort}>执行排序</button> </div> }
内容的提问来源于stack exchange,提问作者Nazar
相关产品推荐
相关产品推荐

