将 React 组件转换为 Typescript?

Posted

技术标签:

【中文标题】将 React 组件转换为 Typescript?【英文标题】:Converting React Component to Typescript? 【发布时间】:2018-02-22 01:00:08 【问题描述】:

我正在尝试将 React+Redux 组件的示例复制到 typescript:https://medium.com/@stowball/a-dummys-guide-to-redux-and-thunk-in-react-d8904a7005d3

我遇到了这个函数的死胡同:

导出默认连接(mapStateToProps, mapDispatchToProps)(ItemList);

我收到一个关于它如何无法映射到 ItemList 的错误。

我认为解决此问题的一种方法是将类声明更改为:

class ItemList extends React.Component<proper component map, proper state map> 

但是,如果我这样做是因为道具现在已经被映射,我不能简单地将 ItemList 包括在内,并且现在需要提供参数。

另一种选择可能是:(props as any).fetchData() 但这感觉不对。

有没有办法解决这个问题?我在 typescript 中做错 React+Redux 了吗?

【问题讨论】:

为什么提供组件需要的参数是个问题? 因为我不能只使用 并且必须提供参数,而在 javascript 示例中我不必这样做。 【参考方案1】:

创建完所有内容后,将其与connect 一起导出。

interface PassedProps 
  productId: number;


interface StateToProps 
  addedProductIds: number[];
  quantityById:  [key: string]: number ;
  quantity: number;


interface DispatchToProps 
  addToCart: (productId: number) => void;
  removeFromCart: (productId: number) => void;


// Needs to be added to src/store:GlobalStore interface with the correct prop name created from the name of the reducer
export interface CartState 
  addedProductIds: number[];
  quantityById:  [key: string]: number ;


const mapStateToProps = (globalState: GlobalState): StateToProps => 
  const state: CartState = globalState.cart;

  return 
    addedProductIds: state.addedProductIds,
    quantityById: state.quantityById,
    quantity: Object.keys(state.quantityById).reduce( (sum: number, key: string) => state.quantityById[key] + sum, 0)
  ;
;


const mapDispatchToProps = (dispatch: Dispatch<any>): DispatchToProps => 
  return 
    addToCart: (productId: number) => dispatch( type: 'ADD_TO_CART', productId  as AddToCartAction),
    removeFromCart: (productId: number) => dispatch( type: 'REMOVE_FROM_CART', productId  as RemoveFromCartAction),
  ;


export type Props = PassedProps & StateToProps & DispatchToProps;

class CartButton extends Component<Props, CartState> 
  render() 
    const  quantity  = this.props;

    return (
      <View>
        <Text>
           this.props.addedProductIds.length  type item is in the cart, totals to  quantity  item.
        </Text>
        <View>
          <Button
            onPress=this.onPressAdd.bind(this)
            title="Add to Cart"
            color="#841584"
          />

          <Button
            onPress=this.onPressRemove.bind(this)
            title="Removefrom Cart"
            color="#841584"
          />
        </View>
      </View>
    );
  

  onPressAdd() 
    this.props.addToCart(this.props.productId);
  

  onPressRemove() 
    this.props.removeFromCart(this.props.productId);
  


export default connect<StateToProps, DispatchToProps, PassedProps>(mapStateToProps, mapDispatchToProps)(CartButton);

然后您可以使用它来指定要传递的所需道具(PassedProps 接口):

import CartButton from '../components/CartButton';

// ....
  render() 
    return(<CartButton productId=5 />)
   

【讨论】:

我试图调整这个例子,但仍然没有成功,组件仍然需要更多的参数,而不仅仅是 productId 我的上帝,我刚刚意识到,按照 Visual Studio 示例,导出在末尾添加了“as typeof”,如下所示:export default connect(mapStateToProps, mapDispatchToProps)(CartButton)作为 typeof CartButton 根据您的示例删除它可以解决所有问题。我无法相信我为此遭受了多少痛苦,我不确定“as typeof”位的用途或实现的目的,但将其排除在外可以解决问题,因此您的示例是有效的。

以上是关于将 React 组件转换为 Typescript?的主要内容,如果未能解决你的问题,请参考以下文章

使用 Typescript 创建 React 组件

使用 TypeScript 在 React 组件外部调度 Redux Thunk 操作

如何将 React 路由器功能转换为 Typescript?

React 将 JSX 应用程序转换为 Typescript

使用 Typescript(TSX 文件)将道具传递给 React 中的子组件

Typescript React:访问组件属性类型