如何在带有 Field 和 FieldArray 的 React 组件中使用由 @types/redux-form 定义的类型? [英] How do I use types defined by @types/redux-form in React component with Field and FieldArray?

查看:72
本文介绍了如何在带有 Field 和 FieldArray 的 React 组件中使用由 @types/redux-form 定义的类型?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用 React、Redux、Redux-Form 和 TypeScript 开发应用程序.我正在努力使用包 @types/redux-form (DefinitelyTyped) 定义的类型,尤其是 FieldArray.有一个属性组件",我在其中传递了对组件的引用,但我不知道在描述它的道具时应该使用什么类型.我从 Redux-Form 存储库 下载了使用 FieldArray 的示例,并稍微修改了它以使用 TypeScript.我想用 compilerOption "noImplicitAny": true 编译它.所以这里是 FieldArraysForm.tsx(类似于官方示例):

import * as React from 'react';import { Field, FieldArray, reduxForm } from 'redux-form';从'./validate'导入验证;const renderField = (props) =>{const { touch, error } = props.meta;const { 输入,标签,类型 } = 道具;返回 (<div><label>{label}</label><div><input {...input} type={type} placeholder={label}/>{感动&&错误&&<span>{错误}</span>}

)}const renderHobbies = (道具) =>{const { 字段 } = 道具;const { 错误 } = props.meta;返回 (<ul><li><button type="button" onClick={() =>fields.push()}>添加爱好{fields.map((hobby, index) => (<li key={index}><按钮类型=按钮"标题="删除爱好"onClick={() =>fields.remove(index)}/><字段姓名={爱好}类型=文本"组件={renderField}标签={`爱好#${index + 1}`}/>))}{错误&&<li className="error">{error}</li>})}const renderMembers = (props) =>{const { 字段 } = 道具;const { 错误,提交失败 } = props.meta;返回 (<ul><li><button type="button" onClick={() =>fields.push({})}>添加成员{提交失败&&错误&&<span>{错误}</span>}{fields.map((member, index) => (<li key={index}><按钮类型=按钮"标题="删除成员"onClick={() =>fields.remove(index)}/><h4>成员#{index + 1}</h4><字段name={`${member}.firstName`}类型=文本"组件={renderField}标签=名字"/><字段name={`${member}.lastName`}类型=文本"组件={renderField}标签=姓氏"/><FieldArray name={`${member}.hobbies`} 组件={renderHobbies}/>))})}const FieldArraysForm = props =>{const { handleSubmit, 原始, 重置, 提交 } = props返回 (<form onSubmit={handleSubmit}><字段名称=俱乐部名称"类型=文本"组件={renderField}标签=俱乐部名称"/><FieldArray name="members" component={renderMembers}/><div><button type="submit" disabled={submitting}>提交<button type="button" disabled={pristine ||submit} onClick={reset}>清除值

</表单>)}导出默认 reduxForm({form: 'fieldArrays',//此表单的唯一标识符证实})(FieldArraysForm)

如何让它与类型一起工作?

解决方案

我找到了解决方案.如果有人和我有同样的问题,我会留下答案.

import * as React from 'react';import { Field, FieldArray, reduxForm, WrappedFieldProps, WrappedFieldArrayProps, InjectedFormProps, GenericFieldArray } from 'redux-form';从'./validate'导入验证;接口 CustomFieldProps {类型?:字符串;}const FieldArrayCustom = FieldArray as new () =>GenericFieldArray;const renderField = (props: WrappedFieldProps & CustomFieldProps) =>{const { touch, error } = props.meta;const { 输入,标签,类型 } = 道具;返回 (<div><label>{label}</label><div><input {...input} type={type} placeholder={label}/>{感动&&错误&&<span>{错误}</span>}

)}const renderHobbies = (props: WrappedFieldArrayProps) =>{const { 字段 } = 道具;const { 错误 } = props.meta;返回 (<ul><li><button type="button" onClick={() =>fields.push(undefined)}>添加爱好{fields.map((hobby, index) => (<li key={index}><按钮类型=按钮"标题="删除爱好"onClick={() =>fields.remove(index)}/><字段姓名={爱好}类型=文本"组件={renderField}标签={`爱好#${index + 1}`}/>))}{错误&&<li className="error">{error}</li>})}const renderMembers = (props: WrappedFieldArrayProps<{}>) =>{const { 字段 } = 道具;const { 错误,submitFailed } = props.meta;返回 (<ul><li><button type="button" onClick={() =>fields.push({})}>添加成员{提交失败&&错误&&<span>{错误}</span>}{fields.map((member, index) => (<li key={index}><按钮类型=按钮"标题="删除成员"onClick={() =>fields.remove(index)}/><h4>成员#{index + 1}</h4><字段name={`${member}.firstName`}类型=文本"组件={renderField}标签=名字"/><字段name={`${member}.lastName`}类型=文本"组件={renderField}标签=姓氏"/><FieldArrayCustom name={`${member}.hobbies`} 组件={renderHobbies}/>))})}const FieldArraysForm = (props: InjectedFormProps) =>{const { handleSubmit, 原始, 重置, 提交 } = props返回 (<form onSubmit={handleSubmit}><字段名称=俱乐部名称"类型=文本"组件={renderField}标签=俱乐部名称"/><FieldArrayCustom name="members" component={renderMembers}/><div><button type="submit" disabled={submitting}>提交<button type="button" disabled={pristine ||submit} onClick={reset}>清除值

</表单>)}导出默认 reduxForm({form: 'fieldArrays',//此表单的唯一标识符证实})(FieldArraysForm)

I'm developing app with React, Redux, Redux-Form and TypeScript. I am struggling to use types defined by package @types/redux-form (DefinitelyTyped), especially with FieldArray. There is an attribute "component" where I pass reference to component, but I have no clue what type should I use when describing its props. I downloaded example of using FieldArray from Redux-Form repository and slightly modified it to work with TypeScript. I want to compile it with compilerOption "noImplicitAny": true. So here is the FieldArraysForm.tsx (similar to official example):

import * as React from 'react';
import { Field, FieldArray, reduxForm } from 'redux-form';
import validate from './validate';

const renderField = (props) => {
  const { touched, error } = props.meta;
  const { input, label, type } = props;

  return (
    <div>
      <label>{label}</label>
      <div>
        <input {...input} type={type} placeholder={label} />
        {touched && error && <span>{error}</span>}
      </div>
    </div>
  )
}

const renderHobbies = (props) => {
  const { fields } = props;
  const { error } = props.meta;
  return (
    <ul>
      <li>
        <button type="button" onClick={() => fields.push()}>
          Add Hobby
        </button>
      </li>
      {fields.map((hobby, index) => (
        <li key={index}>
          <button
            type="button"
            title="Remove Hobby"
            onClick={() => fields.remove(index)}
          />
          <Field
            name={hobby}
            type="text"
            component={renderField}
            label={`Hobby #${index + 1}`}
          />
        </li>
      ))}
      {error && <li className="error">{error}</li>}
    </ul>
  )
}

const renderMembers = (props) => {
  const { fields } = props;
  const { error, submitFailed } = props.meta;

  return (
    <ul>
      <li>
        <button type="button" onClick={() => fields.push({})}>
          Add Member
        </button>
        {submitFailed && error && <span>{error}</span>}
      </li>
      {fields.map((member, index) => (
        <li key={index}>
          <button
            type="button"
            title="Remove Member"
            onClick={() => fields.remove(index)}
          />
          <h4>Member #{index + 1}</h4>
          <Field
            name={`${member}.firstName`}
            type="text"
            component={renderField}
            label="First Name"
          />
          <Field
            name={`${member}.lastName`}
            type="text"
            component={renderField}
            label="Last Name"
          />
          <FieldArray name={`${member}.hobbies`} component={renderHobbies} />
        </li>
      ))}
    </ul>
  )
}

const FieldArraysForm = props => {
  const { handleSubmit, pristine, reset, submitting } = props
  return (
    <form onSubmit={handleSubmit}>
      <Field
        name="clubName"
        type="text"
        component={renderField}
        label="Club Name"
      />
      <FieldArray name="members" component={renderMembers} />
      <div>
        <button type="submit" disabled={submitting}>
          Submit
        </button>
        <button type="button" disabled={pristine || submitting} onClick={reset}>
          Clear Values
        </button>
      </div>
    </form>
  )
}

export default reduxForm({
  form: 'fieldArrays', // a unique identifier for this form
  validate
})(FieldArraysForm)

How do I make it work with types?

解决方案

I found the solution. I'm leaving the answer in case anyone had the same problem as me.

import * as React from 'react';
import { Field, FieldArray, reduxForm, WrappedFieldProps, WrappedFieldArrayProps, InjectedFormProps, GenericFieldArray } from 'redux-form';
import validate from './validate';

interface CustomFieldProps {
  type?: string;
}

const FieldArrayCustom = FieldArray as new () => GenericFieldArray<Field, any>;

const renderField = (props: WrappedFieldProps & CustomFieldProps) => {
  const { touched, error } = props.meta;
  const { input, label, type } = props;

  return (
    <div>
      <label>{label}</label>
      <div>
        <input {...input} type={type} placeholder={label} />
        {touched && error && <span>{error}</span>}
      </div>
    </div>
  )
}

const renderHobbies = (props: WrappedFieldArrayProps<undefined>) => {
  const { fields } = props;
  const { error } = props.meta;

  return (
    <ul>
      <li>
        <button type="button" onClick={() => fields.push(undefined)}>
          Add Hobby
        </button>
      </li>
      {fields.map((hobby, index) => (
        <li key={index}>
          <button
            type="button"
            title="Remove Hobby"
            onClick={() => fields.remove(index)}
          />
          <Field
            name={hobby}
            type="text"
            component={renderField}
            label={`Hobby #${index + 1}`}
          />
        </li>
      ))}
      {error && <li className="error">{error}</li>}
    </ul>
  )
}

const renderMembers = (props: WrappedFieldArrayProps<{}>) => {
  const { fields } = props;
  const { error, submitFailed } = props.meta;

  return (
    <ul>
      <li>
        <button type="button" onClick={() => fields.push({})}>
          Add Member
        </button>
        {submitFailed && error && <span>{error}</span>}
      </li>
      {fields.map((member, index) => (
        <li key={index}>
          <button
            type="button"
            title="Remove Member"
            onClick={() => fields.remove(index)}
          />
          <h4>Member #{index + 1}</h4>
          <Field
            name={`${member}.firstName`}
            type="text"
            component={renderField}
            label="First Name"
          />
          <Field
            name={`${member}.lastName`}
            type="text"
            component={renderField}
            label="Last Name"
          />
          <FieldArrayCustom name={`${member}.hobbies`} component={renderHobbies} />
        </li>
      ))}
    </ul>
  )
}

const FieldArraysForm = (props: InjectedFormProps) => {
  const { handleSubmit, pristine, reset, submitting } = props

  return (
    <form onSubmit={handleSubmit}>
      <Field
        name="clubName"
        type="text"
        component={renderField}
        label="Club Name"
      />
      <FieldArrayCustom name="members" component={renderMembers} />
      <div>
        <button type="submit" disabled={submitting}>
          Submit
        </button>
        <button type="button" disabled={pristine || submitting} onClick={reset}>
          Clear Values
        </button>
      </div>
    </form>
  )
}

export default reduxForm({
  form: 'fieldArrays', // a unique identifier for this form
  validate
})(FieldArraysForm)

这篇关于如何在带有 Field 和 FieldArray 的 React 组件中使用由 @types/redux-form 定义的类型?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
其他开发最新文章
热门教程
热门工具
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆