TypeScript React使用useCallback实现孙组件值向子、父组件传递的方法
React TS 孙组件状态透传到父组件实现方案
核心逻辑:React 下层组件向上传值都是通过上层组件提前传递回调函数,下层组件触发回调时把值作为参数传入即可,孙→子→父的场景只需要子组件做一层回调透传即可,不需要额外引入状态管理库。
第一步:先定义公共类型
替换你代码里的any[],避免TS类型报错,把类型抽成公共文件全局复用即可:
// types.ts export interface MapItem { price: { amount: number; }; // 补充你业务里其他需要的字段 }
第二步:父组件定义接收状态和回调函数
父组件是最终要拿到值的上层组件,先定义好接收状态和处理函数,把函数作为props传给子组件:
// Parent.tsx import React, { useState } from 'react'; import Child from './Child'; import { MapItem } from './types'; const Parent = () => { // 用来接收孙组件传上来的过滤结果 const [receivedFilter, setReceivedFilter] = useState<MapItem[]>([]); // 传给下层的回调函数,参数就是孙组件要传上来的值 const handleFilterUpdate = (filterList: MapItem[]) => { setReceivedFilter(filterList); // 这里写父组件拿到值后的业务逻辑 }; return ( <div> <Child onFilterUpdate={handleFilterUpdate} /> <p>父组件拿到的过滤结果数量:{receivedFilter.length}</p> </div> ); }; export default Parent;
第三步:子组件做回调透传
中间层的子组件不需要存状态,直接把父组件传下来的回调原样传给孙组件即可:
// Child.tsx import React from 'react'; import GrandChild from './GrandChild'; import { MapItem } from './types'; interface ChildProps { onFilterUpdate: (filterList: MapItem[]) => void; } const Child: React.FC<ChildProps> = (props) => { return ( <div> {/* 透传回调给孙组件 */} <GrandChild onFilterUpdate={props.onFilterUpdate} /> </div> ); }; export default Child;
第四步:孙组件触发回调传值
你原来写状态的孙组件,更新完本地状态后,调用props里的回调函数把值传上去即可:
// GrandChild.tsx import React, { useState } from 'react'; import { MapItem } from './types'; interface GrandChildProps { onFilterUpdate: (filterList: MapItem[]) => void; mapdata?: MapItem[]; // 你的原始数据来源,按你实际逻辑调整 } const GrandChild: React.FC<GrandChildProps> = ({ onFilterUpdate, mapdata }) => { const [mapDestinationfilter, setmapDestinationfilter] = useState<MapItem[]>([]); // 给事件对象加TS类型,避免any报错 const onChange = (e: React.ChangeEvent<HTMLInputElement>) => { // input拿到的值默认是字符串,要转成数字再比较 const value = Number(e.target.value); const Destinationfilter = mapdata?.filter(el => el.price.amount < value) || []; setmapDestinationfilter(Destinationfilter); // 触发回调把值传上去 onFilterUpdate(Destinationfilter); }; return ( <div> <input type="number" onChange={onChange} placeholder="输入价格阈值" /> {/* 孙组件自身使用mapDestinationfilter的业务逻辑 */} </div> ); }; export default GrandChild;
注意事项
- 如果后续层级变得更深,不想一层一层透传props,可以用
useContext做跨层级传值,当前3层的场景透传props复杂度更低,不需要额外引入context - 注意输入值的类型转换,避免字符串和数字比较出现的隐式类型转换bug
内容的提问来源于stack exchange,提问作者Farhad
相关产品推荐
相关产品推荐

