Flow新手求助:如何定义融合多来源的React-Redux组件Props类型
嘿,作为Flow新手碰到这种类型合并的问题完全正常!我来帮你一步步实现把组件自身props、Redux映射的state props和action creator props交叉合并成一个完整的Props类型。
先把你提到的State类型和常见的action creators示例先明确下来,再逐步拆解:
1. 基础类型定义
首先先定义你的Redux State和action creators:
// Redux State类型 type State = { state_text: string, state_num: number, }; // 示例action creators(你可以替换成自己的) const setText = (text: string) => ({ type: 'SET_TEXT', payload: text }); const incrementNum = () => ({ type: 'INCREMENT_NUM' });
2. 拆分三类Props
我们需要把不同来源的props拆成独立的类型,再合并:
- OwnProps:组件自身接收的外部传入props(非Redux来源)
- StateProps:通过
mapStateToProps从Redux Store映射过来的props - DispatchProps:通过
mapDispatchToProps注入的action creator props
// 组件自身需要的props(根据你的实际需求调整) type OwnProps = { own_text: string, own_bool: boolean, }; // 从Redux Store映射的props:直接提取State中的需要字段 // 用$Pick可以避免重复定义类型,非常方便 type StateProps = $Pick<State, 'state_text' | 'state_num'>; // 注入的action creator props:用typeof获取函数的类型 type DispatchProps = { setText: typeof setText, incrementNum: typeof incrementNum, };
3. 交叉合并成最终Props类型
用Flow的交叉类型&把三个类型合并,这样组件就能拿到所有来源的props了:
type Props = OwnProps & StateProps & DispatchProps;
4. 完整组件示例
把这些整合到React组件和Redux连接逻辑里,完整代码如下:
import * as React from 'react'; import { connect } from 'react-redux'; // Redux State类型 type State = { state_text: string, state_num: number, }; // 示例action creators const setText = (text: string) => ({ type: 'SET_TEXT', payload: text }); const incrementNum = () => ({ type: 'INCREMENT_NUM' }); // 组件自身接收的props type OwnProps = { own_text: string, own_bool: boolean, }; // Redux映射的state props type StateProps = $Pick<State, 'state_text' | 'state_num'>; // Redux注入的action creator props type DispatchProps = { setText: typeof setText, incrementNum: typeof incrementNum, }; // 合并后的完整Props类型 type Props = OwnProps & StateProps & DispatchProps; // 组件定义:直接使用合并后的Props类型 const MyComponent = (props: Props) => { return ( <div> <p>外部传入文本:{props.own_text}</p> <p>Store中的文本:{props.state_text}</p> <p>Store中的数字:{props.state_num}</p> <button onClick={props.incrementNum}>数字+1</button> <input type="text" value={props.state_text} onChange={(e) => props.setText(e.target.value)} /> </div> ); }; // mapStateToProps:返回StateProps类型的对象 const mapStateToProps = (state: State): StateProps => ({ state_text: state.state_text, state_num: state.state_num, }); // mapDispatchToProps:直接传入action creator对象,Flow会自动匹配类型 const mapDispatchToProps = { setText, incrementNum, }; // 连接组件到Redux export default connect(mapStateToProps, mapDispatchToProps)(MyComponent);
一些小提示
- 如果你的
mapStateToProps需要依赖OwnProps(比如根据组件传入的参数筛选Store数据),只需要保证mapStateToProps的返回值符合StateProps类型即可,不需要修改类型定义。 - 使用
$Pick可以大大简化从State中提取字段的类型定义,避免手动重复写相同的类型。 - 如果你的action creators有更复杂的类型(比如带泛型),可以手动定义函数类型,比如
setText: (text: string) => Action<'SET_TEXT', string>,不过用typeof通常足够应付大多数场景。
内容的提问来源于stack exchange,提问作者Francisco Sarmento
相关产品推荐
相关产品推荐

