首页 > 解决方案 > 带有 React Bootstrap 的 TypeScript 可重用表单

问题描述

我正在关注这篇文章来学习反应和打字稿形式。React Bootstrap 解释了一个可重用的表单,我喜欢实现它。我试图通过编写如下的用户表单来做到这一点。但我明白了

TS7031:绑定元素“取消”隐式具有“任何”类型

一旦我解决了这个错误,我不知道如何使用它。例如,如果我想实现一个登录表单和一个登录表单,我该如何参考下面的用户表单

import React from 'react';
import Form from 'react-bootstrap/Form';
import Button from 'react-bootstrap/Button';
import styled from 'styled-components';

const UserForm =
    ({
        cancel,
        errors,
        submit,
        submitButtonText,
        elements,
        passwordErrors
    }) => {

    function handleSubmit(event) {
        event.preventDefault();
        submit();
    }

    function handleCancel(event) {
        event.preventDefault();
        cancel();
    }

    return (
        <React.Fragment>
            <ErrorsDisplay errors={errors} passwordErrors={passwordErrors} />
            <Form onSubmit={handleSubmit}>
                {elements()}
                <Button className="mr-1" variant="primary" type="submit">{submitButtonText}</Button>
                <Button className="mr-1" variant="secondary" onClick={handleCancel}>Cancel</Button>
            </Form>
        </React.Fragment>
    );
 };

function ErrorsDisplay({ errors, passwordErrors}) {
    let errorDisplay = null;
    if (errors.length) {
        errorDisplay = (
            <React.Fragment>
                <ValidiationLabel>Errors:</ValidiationLabel>
                <ValidiationUl>
                    {errors.map((error, i) => (
                        <li key={i}>{error}</li>
                    ))}
                </ValidiationUl>
            </React.Fragment>
        );
    } else if (!passwordErrors) {
        errorDisplay = (
            <React.Fragment>
                <ValidiationLabel>Errors:</ValidiationLabel>
                <ValidiationUl>{<li>Passwords must match</li>}</ValidiationUl>
            </React.Fragment>
        );
    }
    return errorDisplay;
}

const ValidiationUl = styled.div`
    color: red;
    padding: 15px 0 40px 10px;
  `;
const ValidiationLabel = styled.h2`
    color: #0069c0;
    font-size: 28px;
  `;
export default UserForm;

标签: javascriptreactjstypescriptreact-bootstrap

解决方案


首先,假设您使用的是您所说的 typescript 项目(.tsx 文件扩展名),您需要输入 UserForm 的参数:

// This is just an example, not necessary needs to be this exactly types for the parameters
interface UserFormProps {
  cancel(): void; // cancel is a function that returns nothing
  submit(): void;
  errors: string[]; // errors its an array of strings
  passwordErrors: boolean;
  submitButtonText: string;
  elements(): ReactNode; // elements its a funtion that returns react nodes

}

// Here you are destructuring the object parameter of UserForm function.
// You telling it that its an UserFormProps Type Object on ": UserFormProps"
const UserForm = ({
  cancel,
  submit,
  elements,
  errors,
  submitButtonText,
  passwordErrors,
}: UserFormProps) => { .....

对于 ErrorsDisplay 函数:

interface ErrorsProps {
  errors: string[];
  passwordErrors: boolean;
}

function ErrorsDisplay({ errors, passwordErrors }: ErrorsProps) {...

对于您的句柄函数,您需要指定事件的类型:

// You are saying the handleSubmit function receives an FormEvent from a HTML Form Element
function handleSubmit(event: React.FormEvent<HTMLFormElement>) { ....

// You are saying the handleCancel function receives an MouseEvent from a HTML Button Element
function handleCancel(event: React.MouseEvent<HTMLButtonElement>) { ....

完成此操作后,您可以在任何地方使用您的用户窗体,例如您的登录页面/登录页面。

你只需要导入它:

import React from "react";
import Form from "react-bootstrap/Form";
// here you need to inform the path according to your project
import UserForm from "./UserForms";

const SignIn = () => {
  return (
    <UserForm
      // I'm setting the values ​​hardcoded just as example
      cancel={() => {console.log('cancel')}}
      submit={() => {console.log('submit')}}
      errors={[]}
      passwordErrors={false}
      submitButtonText="test"
      elements={() => (
        <>
          <Form.Group controlId="ControlId">
            <Form.Control
              type="email"
              name="email"
              value={"email@c.com.br"}
              placeholder={"email"}
            ></Form.Control>
            <Form.Control
              type="password"
              name="password"
              value={"password"}
              placeholder={"password"}
            ></Form.Control>
          </Form.Group>
        </>
      )}
    ></UserForm>
  );
};

export default SignIn;

推荐阅读