React HOC TypeScript通过Redux connect摆脱任何类型

问题描述

一般想法是提供翻译功能的包装器组件。

顺便说一句,完整示例在此处https://codesandbox.io/s/quizzical-hellman-v84ed或GitHub https://github.com/hitrov/translation-wrapper

这是HOC签名

export const wrapper = <P extends object>(Component: React.ComponentType<P>) =>
  (props: P & WithReplacementProps & IProps) => {...}

参数组件必须提供以下内容

interface WithReplacementProps {
  translatableProps: {
    getHeader(): string;
    getContent(): string;
  }
}

Redux应该注入

interface IProps {
  language: string;

  setLanguage(language: string): SetLanguage;
}

就是这样

type StateProps = Pick<IProps,| 'language'>;
type dispatchProps = Pick<IProps,| 'setLanguage'>;
type OwnProps = Omit<
  IProps,keyof StateProps | keyof dispatchProps
>;

const connector = connect<StateProps,dispatchProps,OwnProps,RootState>((state: RootState) => ({
  language: state.language,}),{
  setLanguage,});

问题是,当我尝试用可以安全检查类型的内容替换<any>时,总是会遇到TypeScript错误

export function withReplacement<T>(Component: React.ComponentType<T>) {
  return connector(wrapper<any>(Component));
}

这是我最后使用包装组件的方式

const ContentWithReplacement = withReplacement(Content);
...
<ContentWithReplacement
          key={header}
          header={header}
          content={content}
          translatableProps={{
            getContent: () => content,getHeader: () => header,}}
        />

内容组件很简单

export function Content(props: ContentProps) {
  const { translatedProps } = props;

  return (
    <>
      <h1>{translatedProps && translatedProps.header}</h1>
      <p>{translatedProps && translatedProps.content}</p>
    </>
  );
}

解决方法

解决了问题。这对我有很大帮助https://github.com/piotrwitek/react-redux-typescript-guide#--nested-hoc---wrapping-a-component-injecting-props-and-connecting-to-redux-

这就是我当前连接的HOC的样子

import React,{ useReducer,useState } from "react";
import { reducer } from "../reducers";
import { Select } from "../Select";
import { connect } from 'react-redux';
import { RootState } from "../reducers/redux";
import { setLanguage,SetLanguage,} from '../reducers/language';
import { Diff } from 'utility-types';

interface InjectedProps {
  language: string;

  setLanguage(language: string): SetLanguage;
}

interface WithReplacementProps {
  translatableProps: {
    getHeader(): string;
    getContent(): string;
  }
}

export const withReplacement = <BaseProps extends {}>
(Component: React.ComponentType<BaseProps>) => {

  const mapStateToProps = (state: RootState) => ({
    language: state.language,});

  const dispatchProps = {
    setLanguage: (language: string) => setLanguage(language),};

  type PropsFromRedux = ReturnType<typeof mapStateToProps> &
    typeof dispatchProps & {
    // here you can extend ConnectedHoc with new props
    // overrideCount?: number;
  };

  const Hoc = (props: PropsFromRedux & WithReplacementProps) => {

    const { translatableProps,language,setLanguage,...rest } = props;

    const [ showOriginal,setShowOriginal ] = useState(true);

    const { getHeader,getContent } = translatableProps;
    let header = getHeader();
    let content = getContent();

    const [ state,dispatch ] = useReducer(reducer,{...);

    return (
      <>
        <Component
          {...rest as BaseProps}
          translatedProps={{
            header,content,}}
        />
        <Select
          language={language}
          onChange={e => {
            setLanguage(e.target.value);
          }}
        />
      </>
    );
  };

  return connect<ReturnType<typeof mapStateToProps>,typeof dispatchProps,// use "undefined" if NOT using dispatchProps
    Diff<BaseProps,InjectedProps>,RootState>(
    mapStateToProps,dispatchProps
  )(Hoc);
};

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...