使用 TypeScript 和 React 键入 redux 表单 v7 [英] Typing redux forms v7 with TypeScript and React

查看:17
本文介绍了使用 TypeScript 和 React 键入 redux 表单 v7的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个简单的由 react-redux 驱动的表单.我希望有一个 form.container.tsx 和一个 form.component.tsx,其中 form.container.tsx 保存所有与 redux 状态的连接减去 Field 的连接.我正在尝试将我的容器包装在 react-redux 的连接中,然后将 reduxForm 包装在其中,使其看起来像 TypeScript、redux-form 和连接:

(理想的)form.container.tsx:

interface DummyFormContainerProps {}export const DummyFormContainer: React.SFC= 道具 =>{const submitForm = (formValues: object) =>{警报(formValues);};返回 (<虚拟表格onSubmit={submitForm}/>);};const mapStateToProps = (state: State) =>({});const mapDispatchToProps = (dispatch: object) =>{返回 {};};const mergeProps = (stateProps: State, dispatchProps: object | null, ownProps: object | void) =>Object.assign({}, stateProps, dispatchProps, ownProps);const formConfiguration = {形式:'虚拟形式',forceUnregisterOnUnmount: 真};导出默认连接(mapStateToProps,mapDispatchToProps)(reduxForm(formConfiguration)(DummyFormContainer));

以上不起作用,但如果我去掉 reduxForm() 部分,我会留下一个没有 reduxForm 集成的工作容器:

(在没有 reduxForm 的情况下工作)form.container.tsx:

export default connect(mapStateToProps, mapDispatchToProps, mergeProps)(虚拟表单容器);

我已经尝试过使用 reduxForms 和 connect 的不同变体,但目前都无法正常工作:

(带类)form.container.tsx:

export class DummyFormContainer extends React.Component{submitForm = (formValues: object) =>{警报(formValues);}使成为() {返回 (<虚拟表格onSubmit={this.submitForm}/>);}}const mapStateToProps = (state: State) =>({});const mapDispatchToProps = (dispatch: object) =>{返回 {};};const mergeProps = (stateProps: State, dispatchProps: object | null, ownProps: object | void) =>Object.assign({}, stateProps, dispatchProps, ownProps);const formConfiguration = {表格:'商业登记',};导出默认连接(mapStateToProps,mapDispatchToProps,mergeProps)(reduxForm(formConfiguration)(DummyFormContainer)//错误);

错误:

./src/modules/dummy-form/dummy-form.container.tsx(100,32):错误 TS2345:typeof DummyFormContainer"类型的参数不可分配给ComponentType>"类型的参数.类型typeof DummyFormContainer"不可分配给类型StatelessComponent>".类型 'typeof DummyFormContainer' 不匹配签名 '(props: InjectedFormProps<{}, {}> & { children?: ReactNode; }, context?: any): ReactElement<any>|空值'.

(带有无状态功能组件)form.container.tsx:

export const DummyFormContainer: React.SFC= 道具 =>{const submitForm = (formValues: object) =>{警报(formValues);};返回 (<虚拟表格onSubmit={submitForm}/>);};导出默认连接(mapStateToProps,mapDispatchToProps,mergeProps)(reduxForm(formConfiguration)(DummyFormContainer)//错误);

错误:

./src/modules/dummy-form/dummy-form.container.tsx(100,3):错误 TS2345:DecoratedComponentClass<{}, Partial>>"类型的参数不可分配给类型为 'ComponentType<(State & null & void) | 的参数(状态 & null & 对象) |(状态&对象&无效)|(状态 ...'.输入DecoratedComponentClass<{}、Partial>>"不可分配到类型 'StatelessComponent<(State & null & void) |(状态 & null & 对象) |(状态&对象&无效)|(S...'.输入DecoratedComponentClass<{}、Partial>>"不匹配签名 '(props: (State & null & void & { children?: ReactNode; }) | (State & null & object & { children?: ReactNode; }) | (State& object & void & { children?: ReactNode; }) | (State & object & { children?: ReactNode; }), context?: any): ReactElement

form.component.tsx 看起来像这样:

import * as React from 'react';从'../../components/input'导入输入;接口 DummyFormProps {onSubmit: (formValues: object) =>空白}export const DummyForm: React.SFC= () =>{返回 (<div><h1>DummyForm(无状态)</h1><表格><Input inputType="primary"/></表单>

);};导出默认 DummyForm;

而 <Input > 组件是一个常规的 React 组件.

有谁知道如何正确连接reduxForm和react-redux的connect()?

解决方案

我在尝试从 redux 状态初始化表单时也遇到了这个问题,如 https://redux-form.com/7.0.4/examples/initializefromstate/

我最终通过在更高级别连接组件来解决它,例如:

component.tsx:

interface DummyFormComponentProps {} extends InjectedFormPropsconst DummyFormComponent: React.SFC= 道具 =>{返回 (<form onSubmit={props.handleSubmit}>//字段放在这里</表单>)}export const DummyForm = reduxForm({形式:虚拟形式"})(DummyFormComponent)//尝试在此处连接也会出现 DecoratedComponentClass 的错误

容器.tsx:

interface DummyFormContainerProps {} extends Pick{警报(formValues);};const DummyFormContainer: React.SFC= 道具 =>{返回 (<虚拟表格初始值={props.initialValues}onSubmit={submitForm}/>)}const mapStateToProps = (state: State) =>({初始值:{}});const mapDispatchToProps = (dispatch: object) =>{返回 {};};导出默认连接(mapStateToProps,mapDispatchToProps)(DummyFormContainer)

I've got a plain react-redux-powered form. I wish for there to be a form.container.tsx and a form.component.tsx, where form.container.tsx holds all the connections to redux state minus the Field's. I'm trying to wrap my container in react-redux's connect and then wrapping reduxForm within it to look something like TypeScript, redux-form and connect:

(ideal) form.container.tsx:

interface DummyFormContainerProps {}

export const DummyFormContainer: React.SFC<DummyFormContainerProps> = props => {
  const submitForm = (formValues: object) => {
    alert(formValues);
  };
  return (
    <DummyForm
      onSubmit={submitForm}
    />
  );
};

const mapStateToProps = (state: State) => ({});
const mapDispatchToProps = (dispatch: object) => {
  return {};
};
const mergeProps = (stateProps: State, dispatchProps: object | null, ownProps: object | void) => 
  Object.assign({}, stateProps, dispatchProps, ownProps);

const formConfiguration = {
  form: 'dummy-form',
  forceUnregisterOnUnmount: true
};

export default connect(mapStateToProps, mapDispatchToProps)(
  reduxForm(formConfiguration)(DummyFormContainer)
);

The above does not work, but if I take out the reduxForm() part, I'm left with a working container with no reduxForm Integration:

(working without reduxForm) form.container.tsx:

export default connect(mapStateToProps, mapDispatchToProps, mergeProps)(
  DummyFormContainer
);

And I've tried different variations with reduxForms and connect, all not currently working:

(with classes) form.container.tsx:

export class DummyFormContainer extends React.Component<DummyFormContainerProps, void> {
  submitForm = (formValues: object) => {
    alert(formValues);
  }

  render() {
    return (
      <DummyForm
        onSubmit={this.submitForm}
      />
    );
  }
}

const mapStateToProps = (state: State) => ({});
const mapDispatchToProps = (dispatch: object) => {
  return {};
};
const mergeProps = (stateProps: State, dispatchProps: object | null, ownProps: object | void) => 
  Object.assign({}, stateProps, dispatchProps, ownProps);

const formConfiguration = {
  form: 'business-registration',
};

export default connect(mapStateToProps, mapDispatchToProps, mergeProps)(
  reduxForm(formConfiguration)(DummyFormContainer) // ERROR
);

error:

./src/modules/dummy-form/dummy-form.container.tsx
(100,32): error TS2345: Argument of type 'typeof DummyFormContainer' is not assignable to parameter of type 'ComponentType<InjectedFormProps<{}, {}>>'.
  Type 'typeof DummyFormContainer' is not assignable to type 'StatelessComponent<InjectedFormProps<{}, {}>>'.
    Type 'typeof DummyFormContainer' provides no match for the signature '(props: InjectedFormProps<{}, {}> & { children?: ReactNode; }, context?: any): ReactElement<any> | null'.

(with stateless functional components) form.container.tsx:

export const DummyFormContainer: React.SFC<DummyFormContainerProps> = props => {
  const submitForm = (formValues: object) => {
    alert(formValues);
  };
  return (
    <DummyForm
      onSubmit={submitForm}
    />
  );
};

export default connect(mapStateToProps, mapDispatchToProps, mergeProps)(
  reduxForm(formConfiguration)(DummyFormContainer) // ERROR
);

error:

./src/modules/dummy-form/dummy-form.container.tsx
(100,3): error TS2345: Argument of type 'DecoratedComponentClass<{}, Partial<ConfigProps<{}, {}>>>' is not assignable to parameter of type 'ComponentType<(State & null & void) | (State & null & object) | (State & object & void) | (State ...'.
  Type 'DecoratedComponentClass<{}, Partial<ConfigProps<{}, {}>>>' is not assignable to type 'StatelessComponent<(State & null & void) | (State & null & object) | (State & object & void) | (S...'.
    Type 'DecoratedComponentClass<{}, Partial<ConfigProps<{}, {}>>>' provides no match for the signature '(props: (State & null & void & { children?: ReactNode; }) | (State & null & object & { children?: ReactNode; }) | (State & object & void & { children?: ReactNode; }) | (State & object & { children?: ReactNode; }), context?: any): ReactElement<any> | null'.

The form.component.tsx looks like this:

import * as React from 'react';
import Input from '../../components/input';

interface DummyFormProps {
  onSubmit: (formValues: object) => void
}

export const DummyForm: React.SFC<DummyFormProps> = () => {
  return (
    <div>
      <h1>DummyForm (no state)</h1>
      <form>
        <Input inputType="primary" />
      </form>
    </div>
  );
};

export default DummyForm;

And the < Input > component is a regular React component.

Does anyone know how to properly connect reduxForm and react-redux's connect()?

解决方案

I also ran into this issue trying to initialise my form from redux state, as per the example in https://redux-form.com/7.0.4/examples/initializefromstate/

I ended up getting around it by connecting the component at a higher level, eg:

component.tsx:

interface DummyFormComponentProps {} extends InjectedFormProps

const DummyFormComponent: React.SFC<DummyFormComponentProps> = props => {
  return (
    <form onSubmit={props.handleSubmit}>
      // Fields go here
    </form>
  )
}

export const DummyForm = reduxForm({
  form: "dummy-form"
})(DummyFormComponent)

// Trying to connect here also gave errors with DecoratedComponentClass

container.tsx:

interface DummyFormContainerProps {} extends Pick<InjectedFormProps,
  "initialValues"
>

const submitForm = (formValues: object) => {
  alert(formValues);
};

const DummyFormContainer: React.SFC<DummyFormContainerProps> = props => {  
  return (
    <DummyForm 
      initialValues={props.initialValues}
      onSubmit={submitForm}
    />
  )
}

const mapStateToProps = (state: State) => ({
  initialValues: {}
});
const mapDispatchToProps = (dispatch: object) => {
  return {};
};
export default connect(mapStateToProps, mapDispatchToProps)(DummyFormContainer)

这篇关于使用 TypeScript 和 React 键入 redux 表单 v7的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆