React类组件转Hooks时如何实现onChange事件的同步执行逻辑
React Hooks下拉列表状态更新后执行回调的实现方案
你当前写法无法达到预期的原因是:React 的 useState 状态更新是批量异步执行的,调用props.changeSelectedFilter后父组件的selectedFilter不会立刻变更,紧随其后调用props.chargeInfo时拿到的仍是更新前的旧值,和类组件setState第二个回调的执行逻辑不一致。可以通过以下两种标准方案实现需求:
方案1:父组件通过useEffect监听状态变化(最符合Hooks设计规范,推荐)
在父组件内新增useEffect,将selectedFilter作为依赖项,状态更新后会自动触发chargeInfo执行,和原类组件的逻辑完全等价。
父组件代码修改示例:
// 父组件原有状态定义 const [selectedFilter, setSelectedFilter] = useState('默认值'); // 新增useEffect监听selectedFilter变化 useEffect(() => { chargeInfo(); }, [selectedFilter]); // 传给子组件的changeSelectedFilter方法 const changeSelectedFilter = (val) => { setSelectedFilter(val); };
子组件的下拉回调可以直接简化,不需要再主动调用chargeInfo:
<Dropdown onChange={onChangeDropdown} /> const onChangeDropdown = function(event) { props.changeSelectedFilter(event.target.value); }
方案2:直接传递新值给chargeInfo(无需调整父组件结构,改造成本低)
如果不想修改父组件的现有逻辑,也可以直接将新选择的过滤值作为参数传给chargeInfo,不需要等待状态更新完成即可拿到最新值:
子组件代码修改示例:
const onChangeDropdown = function(event) { const newFilterVal = event.target.value; props.changeSelectedFilter(newFilterVal); props.chargeInfo(newFilterVal); // 直接传入最新的过滤值 }
父组件的chargeInfo同步调整为优先接收参数即可:
const chargeInfo = (filterVal = selectedFilter) => { // 原有逻辑优先使用传入的filterVal,无参数时降级使用当前状态的selectedFilter }
注意:不要尝试通过异步等待、定时器等hack方式等待状态同步更新,上述两种方案是React官方推荐的标准实现方式。
内容的提问来源于stack exchange,提问作者Santiago Amaro
相关产品推荐
相关产品推荐

