将自定义和第三方React表单组件与Ant设计和Typescript一起使用

The React ecosystem has a vast amount of components and libraries that you can use to easily build web applications. The Ant Design library is one of those which provides a great range of ready to go React components, complete with styling for the whole site.

React生态系统具有大量的组件和库,您可以使用它们轻松地构建Web应用程序。 Ant Design库是其中之一,它提供了很多现成的React组件,并为整个站点提供了样式。

In this article, we’ll look into how we can build a custom input to interact with the Ant Design Form component, and add a 3rd party component in order to provide greater functionality.

在本文中,我们将研究如何构建自定义输入以与Ant Design Form组件进行交互,并添加第3方组件以提供更大的功能。

建立 (Setup)

Let’s start by cloning the baseline (https://github.com/chilledoj/antd-custom-form-app) repo and installing the dependencies with Yarn.

让我们首先克隆基线( https://github.com/chilledoj/antd-custom-form-app )回购并使用Yarn安装依赖项。

git clone [email protected]:chilledoj/antd-custom-form-app.gitcd antd-custom-form-appyarn

You should now be able to run the app with yarn start which will open localhost:1234 in your browser.

现在,您应该能够使用yarn start运行应用程序,它将在浏览器中打开localhost:1234

将自定义和第三方React表单组件与Ant设计和Typescript一起使用_第1张图片
Simple Antd form with username input 带有用户名输入的简单Antd表单

You can enter a username into the form and the JSON object of the form values is displayed.

您可以在表单中输入用户名,并显示表单值的JSON对象。

将自定义和第三方React表单组件与Ant设计和Typescript一起使用_第2张图片
Form values received and displayed 表单值已接收并显示

背景 (Background)

App / index.tsx (App/index.tsx)

The App component is the main container for the form component. Rather than use a router, we are just using a null check on the state within the App component to decide whether to display the form or the results of the form. We also pass in some handlers to set and clear the results. The onSubmit handler could also have included an async request to an API and/or dispatch to a redux store.

App组件是表单组件的主要容器。 而不是使用路由器,我们只是对App组件内的状态使用空检查来决定是显示表单还是显示表单结果。 我们还传入一些处理程序来设置和清除结果。 onSubmit处理程序还可能包括对API的异步请求和/或分派给Redux存储。

const App: FC = () => {
const [vals, setVals] = useState(null); const onSubmit = (values: unknown): void => {
setVals(values);
}; const clearValues = (): void => {
setVals(null);
}; ... return ( ... {vals === null ? (

) : (

)}
);
};

We could have written a type for the state, but we’ll ignore that for the time being.

我们可以为状态编写一个类型,但是暂时将其忽略。

组件/Form.tsx (components/Form.tsx)

As per the Ant Design docs, we first set up a Form ref with the useForm hook and ensure it is passed into the form component. We create a wrapper handler onFinish that will run when the form is submitted and will extract the actual form values from the form component and pass these onto the onSubmit handler. Each form item is wrapped in the Form.Item container.

根据Ant Design文档,我们首先使用useForm钩子设置Form ref,并确保将其传递到form组件中。 我们创建了一个包装处理程序onFinish ,该处理程序将在提交表单时运行,并将从表单组件中提取实际的表单值,并将其传递给onSubmit处理程序。 每个表单项都包装在Form.Item容器中。

const TestForm: FC = ({ onSubmit }: TestFormProps) => {
const [form] = Form.useForm();
const onFinish = (): void => {
onSubmit(form.getFieldsValue());
}; return (







);
};

自定义组件 (A Custom Component)

Create a new file in the components directory called MyInput.tsx. In this, we will create a simple HTML input element that is controlled by the Antd form.

在组件目录中创建一个名为MyInput.tsx的新文件。 在此,我们将创建一个由Antd表单控制的简单HTML输入元素。

The docs state that for an element to be controlled correctly within the form, the component must have a value and onChange prop.

文档指出,要在表单中正确控制元素,组件必须具有valueonChange属性。

Let’s create our component.

让我们创建我们的组件。

import React, {FC} from 'react';
const styles = {
wrapper: {
display: "block",
width: "100%"
},
input: {
fontFamily: "monospace",
display: "block",
width: "100%"
}
};interface OnChangeHandler {
(e): void;
}interface MyInputProps {
value: number;
onChange: OnChangeHandler;
}const MyInput: FC = ({value, onChange}: MyInputProps) => {
return (



);
}
export default MyInput;

And now let’s use this component within the Form. Edit Form.tsx to include our new component.

现在,让我们在表单中使用此组件。 编辑Form.tsx以包括我们的新组件。

...return (





{/* @ts-ignore */}

N.B. the {/* @ts-ignore */} bit just tells typescript linters to ignore the fact that we are not explicitly setting the required props of the component. The Form.Item component will take care of passing those in from the form for us.

注意, {/* @ts-ignore */}位只是告诉打字机短毛绒忽略了我们没有明确设置组件所需道具的事实。 Form.Item组件将负责将表单中的内容传递给我们。

You should now see our number input in the form and submitting shows that the form component is receiving the value of the input correctly.

现在,您应该在表单中看到我们的数字输入,并且提交显示表单组件正在正确接收输入的值。

将自定义和第三方React表单组件与Ant设计和Typescript一起使用_第3张图片
Custom number input within Antd form 在Antd表单中输入自定义号码

内部状态 (Internal State)

Our component might need to handle the internal state to provide richer functionality and have a separate handler for the onChange event.

我们的组件可能需要处理内部状态以提供更丰富的功能,并为onChange事件提供单独的处理程序。

We can easily create a custom trigger, that then sends the relevant data back out to the parent Form.Item through the onChange handler.

我们可以轻松地创建一个自定义触发器,然后通过onChange处理程序将相关数据发送回父Form.Item

Let’s do something a little funky. We’ll create an interval callback that increases the number input periodically.

让我们做一些时髦的事情。 我们将创建一个间隔回调,以定期增加输入的数量。

Install the ahooks library with yarn add ahooks. We can then update our input to use the useInterval hook within the library.

使用yarn add ahooks安装ahooks库。 然后,我们可以更新输入以使用库中的useInterval挂钩。

import React, { FC, useState } from 'react';
import { useInterval } from 'ahooks';
...
type OnChangeHandler = (num: number) => void;interface MyInputProps {
value: number;
onChange: OnChangeHandler;
}const MyInput: FC = ({ value, onChange }: MyInputProps) => {
const [val, setVal] = useState(value || 0);
useInterval(() => {
setVal(Number(val || 0) + 1);
onChange(Number(val || 0) + 1);
}, 2500);
const mdlChange = (e: React.ChangeEvent): void => {
setVal(Number(e.target.value));
onChange(Number(e.target.value));
}; return (



);
};export default MyInput;

Within the interval callback, we set both the internal state (which is used by the input element) and send the same back through the onChange handler.

在时间间隔回调中,我们既设置了内部状态(由输入元素使用), onChange通过onChange处理程序发送回去。

We create a separate handler for the onChange of the input element called mdlChange which can then also set the internal state and update the parent form element.

我们为输入元素的onChange创建了一个单独的处理程序,称为mdlChange ,该处理程序还可以设置内部状态并更新父表单元素。

将自定义和第三方React表单组件与Ant设计和Typescript一起使用_第4张图片
Custom number input that auto increases 自定义数字输入会自动增加

第三方图书馆 (Third-Party Libraries)

We may want to integrate other third-party libraries that have their own way of dealing with the state of the component and notifying changes. Most should adhere to the same standard though whereby the value and onChange props are provided.

我们可能希望集成其他第三方库,它们具有处理组件状态和通知更改的方式。 尽管大多数提供的valueonChange道具都应遵循相同的标准。

If the component decides to have a different way of providing the underlying data value, then the Form.Item Antd component has the getValueProps property which tells the form how to extract out the value to provide to the Form from the returned data.

如果组件决定采用其他方式提供基础数据值,则Form.Item Antd组件具有getValueProps属性,该属性告诉表单如何从返回的数据中提取要提供给Form的值。

The React Markdown Editor Lite (https://www.npmjs.com/package/react-markdown-editor-lite) has both the value and onChange properties. However, the data returned back from the component is an object with both the underlying markdown text and the rendered html along with the change event from the underlying textarea.

React Markdown编辑器精简版( https://www.npmjs.com/package/react-markdown-editor-lite )具有value和onChange属性。 但是,从组件返回的数据是一个具有基础markdown文本和呈现的html以及基础textarea的change事件的对象。

/// https://github.com/HarryChen0506/react-markdown-editor-lite/blob/master/src/editor/index.tsx...interface EditorProps extends EditorConfig {
...
value?: string;
onChange?: (
data: {
text: string;
html: string;
},
event?: React.ChangeEvent,
) => void;
...
}

Install this library and markdown-it which is required to render the markdown to html.

安装此库和markdown-it ,这是将markdown呈现为html所必需的。

yarn add react-markdown-editor-lite markdown-it

Now let’s look to add this into the Form component.

现在,让我们将其添加到Form组件中。

/// components/Form.tsx...
import MarkdownIt from 'markdown-it';
import MdEditor from 'react-markdown-editor-lite';
import 'react-markdown-editor-lite/lib/index.css';
...// Initialize a markdown parser
const mdParser = new MarkdownIt({
html: false,
linkify: true,
typographer: true,
});

Now when we go to add the editor within a Form.Item, we just need to tell that component how to extract the value we need, from the data object sent from the markdown editor.

现在,当我们在Form.Item添加编辑器时,我们只需要告诉该组件如何从markdown编辑器发送的data对象中提取所需的值即可。

  name="description"
label="Full Description"
getValueFromEvent={(data): string => data.text} // extract the value from the data object
>
style={{ height: '500px' }}
renderHTML={(text): string => mdParser.render(text)}
/>
Markdown editor added into the form Markdown编辑器添加到表单中
将自定义和第三方React表单组件与Ant设计和Typescript一起使用_第5张图片
Raw markdown text available in form submission 原始Markdown文本可在表单提交中使用

摘要 (Summary)

There are so many UI component libraries for React that provide the building blocks for most apps. The Ant Design library comes with some fantastic components, but there could always be a need to adapt or add custom components. The extensible configuration options provide the ability to do this very easily, and with the addition of Typescript, it becomes easier to peek at what the expected value types from third-party libraries should be.

React有许多UI组件库,它们为大多数应用程序提供了构建块。 Ant Design库带有一些出色的组件,但是始终可能需要调整或添加自定义组件。 可扩展的配置选项提供了非常容易执行此操作的能力,并且通过添加Typescript,可以更轻松地查看第三方库的期望值类型。

翻译自: https://medium.com/swlh/use-custom-and-third-party-react-form-components-with-ant-design-and-typescript-2732e7849aee

你可能感兴趣的:(react,python,javascript,ViewUI)