如何使用 React 和语义 UI 创建多步骤表单

介绍

表单用于在 Web 应用程序中收集用户输入,但是,您可能遇到需要从用户收集大量信息的情况,这可能导致大量的字段。

一个解决方案是将表单分成多个部分(或步骤),每个部分在每个点上收集某种类型的信息。

在本教程中,您将使用 React 和 Semantic UI 构建一个多步登记表格. 您可以通过使用每个部分的 React 组件来实现这一目标. 然后您可以通过操纵状态来选择在每个步骤中渲染的组件。

前提条件

要完成本教程,您将需要:

本教程已通过 Node v14.0.0、npm v6.14.4、react v16.13.1、semantic-ui-react v0.88.2 和 semantic-ui-css v2.4.1 进行验证。

步骤 1 — 使用语义界面界面初始化一个新的React项目

首先,您将使用 npx 使用 create-react-app 生成您的项目。

在您的终端中,运行以下操作:

1npx create-react-app multistep-form

这将创建一个React样本应用程序,开发环境已完全配置。

接下来,更改新创建的项目目录:

1cd multistep-form

要在您的 React 应用程序中使用 Semantic UI,您将使用Semantic UI React. Semantic UI React 提供了预建的组件,您可以使用它们来加快开发过程。

它还支持响应式网页设计,这使得它非常适合构建跨平台网站。

在您的终端中,运行以下操作:

1npm install [email protected]

接下来,您还将包含默认主题。

在您的终端中,运行以下操作:

1npm install [email protected]

若要添加自定义 Semantic UI CSS,请打开index.js文件:

1nano src/index.js

并添加以下进口:

1[label src/index.js]
2import React from 'react';
3import ReactDOM from 'react-dom';
4import 'semantic-ui-css/semantic.min.css';
5import './index.css';
6import App from './App';
7import * as serviceWorker from './serviceWorker';

现在React项目已经初始化,您已经添加了必要的依赖,您可以开始创建您的组件。

步骤2 - 创建组件

在本教程的步骤中,您将添加创建五个组件:

  • 「MainForm.jsx」 * 「UserDetails.jsx」 * 「PersonalDetails.jsx」 * 「Confirmation.jsx」 * 「Success.jsx」

首先,让我们编辑App.js来导入组件并渲染它们:

1nano src/App.js

用以下代码代码代替create-react-app生成的所有锅炉板代码:

 1[label src/App.js]
 2import React, { Component } from 'react';
 3import { Grid } from 'semantic-ui-react';
 4import './App.css';
 5import MainForm from './components/MainForm';
 6
 7class App extends Component {
 8  render() {
 9    return (
10      <Grid verticalAlign='middle' style={{ height: '100vh' }}>
11        <MainForm />
12      </Grid>
13    );
14  }
15}
16
17export default App;

注意: 如果您现在启动开发服务器,您将遇到错误,直到您完成编写和导入表单的所有组件。

在此代码中,您已经使用了 Semantic UI React 的网格组件,通过将文本中心化并添加插件来使其更加可呈现。

您还导入并使用了MainForm组件,现在就来处理一下。

构建MainForm组件

您将设置的第一个组件是MainForm.jsx组件,该组件将负责您的应用程序中的大多数功能。

让我们在src目录下创建一个组件文件夹:

1mkdir src/components

然后创建一个Mainform.jsx文件:

1nano src/components/MainForm.jsx

添加以下代码行:

1[label src/components/MainForm.jsx]
2import React, { Component } from 'react';
3import UserDetails from './UserDetails';
4import PersonalDetails from './PersonalDetails';
5import Confirmation from './Confirmation';
6import Success from './Success';

此代码将导入依赖性,还将导入表单的四个部分:用户细节,个人细节,确认成功

然后,在导入下方,为MainForm组件添加状态:

 1[label src/components/MainForm.jsx]
 2// ...
 3
 4class MainForm extends Component {
 5  state = {
 6    step: 1,
 7    firstName: '',
 8    lastName: '',
 9    email: '',
10    age: '',
11    city: '',
12    country: ''
13  }
14}
15
16export default MainForm;

FirstName,lastName,email,age,citycountry是您对最终用户提供信息感兴趣的领域。

步骤将是从14的数字,这将允许您跟踪当前用户在多步进程中的哪个步骤。

然后,添加nextStep,prevStephandleChange函数:

 1[label src/components/MainForm.jsx]
 2// ...
 3
 4class MainForm extends Component {
 5  // ...
 6
 7  nextStep = () => {
 8    const { step } = this.state
 9    this.setState({
10      step : step + 1
11    })
12  }
13
14  prevStep = () => {
15    const { step } = this.state
16    this.setState({
17      step : step - 1
18    })
19  }
20
21  handleChange = input => event => {
22    this.setState({[input]: event.target.value})
23  }
24}
25
26// ...

该组件被初始化为状态中的步骤的默认值为1,然后将表单的第一个部分渲染。用户可以使用prevStepnextStep函数在步骤之间跳过。

handleChange函数更新了用户内部状态提供的细节的值,就像prevStepnextStep函数一样,它将作为附件传递给儿童组件。

然后,添加返回函数:

 1[label src/components/MainForm.jsx]
 2// ...
 3
 4class MainForm extends Component {
 5  // ...
 6
 7  render() {
 8    const { step } = this.state;
 9    const { firstName, lastName, email, age, city, country } = this.state;
10    const values = { firstName, lastName, email, age, city, country };
11
12    switch(step) {
13      case 1:
14        return <UserDetails
15                  nextStep={this.nextStep} 
16                  handleChange = {this.handleChange}
17                  values={values}
18                />
19      case 2:
20        return <PersonalDetails
21                  nextStep={this.nextStep}
22                  prevStep={this.prevStep}
23                  handleChange = {this.handleChange}
24                  values={values}
25                />
26      case 3:
27        return <Confirmation
28                  nextStep={this.nextStep}
29                  prevStep={this.prevStep}
30                  values={values}
31                />
32      case 4:
33        return <Success />
34    }
35  }
36}
37
38// ...

多步表格使用交换语句,该语句读取状态中的步骤,并使用此语句来选择在每个步骤中渲染的组件。

步骤 1 中,将渲染用户详细信息组件,在** 步骤 2** 中,将渲染个人详细信息组件,在** 步骤 3** 中,将渲染确认组件,在** 步骤 4** 中将渲染成功组件。

您的MainForm组件现在已经完成。

构建用户细节组件

现在,让我们创建表单的第一个部分。

创建一个UserDetails.jsx文件:

1nano src/components/UserDetails.jsx

添加以下代码行:

 1[label src/components/UserDetails.jsx]
 2import React, { Component } from 'react';
 3import { Grid, Header, Segment, Form, Button } from 'semantic-ui-react';
 4
 5class UserDetails extends Component {
 6  saveAndContinue = (e) => {
 7    e.preventDefault();
 8    this.props.nextStep();
 9  }
10
11  render() {
12    const { values } = this.props;
13
14    return (
15      <Grid.Column style={{ maxWidth: 450 }}>
16        <Header textAlign='center'>
17          <h1>Enter User Details</h1>
18        </Header>
19
20        <Form>
21          <Segment>
22            <Form.Field>
23              <label>First Name</label>
24              <input
25                placeholder='First Name'
26                onChange={this.props.handleChange('firstName')}
27                defaultValue={values.firstName}
28              />
29            </Form.Field>
30
31            <Form.Field>
32              <label>Last Name</label>
33              <input
34                placeholder='Last Name'
35                onChange={this.props.handleChange('lastName')}
36                defaultValue={values.lastName}
37              />
38            </Form.Field>
39
40            <Form.Field>
41              <label>Email Address</label>
42              <input
43                type='email'
44                placeholder='Email Address'
45                onChange={this.props.handleChange('email')}
46                defaultValue={values.email}
47              />
48            </Form.Field>
49          </Segment>
50
51          <Segment>
52            <Button onClick={this.saveAndContinue}>Save And Continue</Button>
53          </Segment>
54        </Form>
55      </Grid.Column>
56    );
57  }
58}
59
60export default UserDetails;

这会创建一个收集用户姓名、姓名和电子邮件地址的表格。

然后,保存和继续函数负责将用户路由到下一个组件,一旦他们完成了填写细节。

您会注意到,您已将您提供给组件的).您还称为handleChange,并在每个输入元素上提供每个字段的名称。

您也可能注意到,每个输入字段都提供了一个默认值,它从MainForm组件的状态中选择它,这允许它在用户从另一个阶段返回路由的情况下选择更新的状态值。

您的用户细节组件现在已经完成。

构建个人细节组件

现在,让我们创建你的第二部分,该部分收集用户的个人信息。

创建一个PersonalDetails.jsx文件:

1nano src/components/PersonalDetails.jsx

添加以下代码行:

 1[label src/components/PersonalDetails.jsx]
 2import React, { Component } from 'react';
 3import { Grid, Header, Segment, Form, Button } from 'semantic-ui-react';
 4
 5class PersonalDetails extends Component {
 6  saveAndContinue = (e) => {
 7    e.preventDefault();
 8    this.props.nextStep();
 9  }
10
11  back = (e) => {
12    e.preventDefault();
13    this.props.prevStep();
14  }
15
16  render() {
17    const { values } = this.props;
18
19    return (
20      <Grid.Column style={{ maxWidth: 450 }}>
21        <Header textAlign='center'>
22          <h1>Enter Personal Details</h1>
23        </Header>
24
25        <Form>
26          <Segment>
27            <Form.Field>
28              <label>Age</label>
29              <input placeholder='Age'
30                onChange={this.props.handleChange('age')}
31                defaultValue={values.age}
32              />
33            </Form.Field>
34
35            <Form.Field>
36              <label>City</label>
37              <input placeholder='City'
38                onChange={this.props.handleChange('city')}
39                defaultValue={values.city}
40              />
41            </Form.Field>
42
43            <Form.Field>
44              <label>Country</label>
45              <input placeholder='Country'
46                onChange={this.props.handleChange('country')}
47                defaultValue={values.country}
48              />
49            </Form.Field>
50          </Segment>
51
52          <Segment textAlign='center'>
53            <Button onClick={this.back}>Back</Button>
54
55            <Button onClick={this.saveAndContinue}>Save And Continue</Button>
56          </Segment>
57        </Form>
58      </Grid.Column>
59    )
60  }
61}
62
63export default PersonalDetails;

该部分收集用户的年龄和位置. 整体功能类似于用户详细信息部分,除了添加 返回 按钮,该按钮将让用户通过拨打prevStep从赞助商返回上一步。

您在每个组件中有)为参数,并在这些函数中呼叫event.preventDefault()`,以阻止表单每次用户提交时重新加载,这是表单中的默认行为。

您的个人细节组件现在已经完成。

构建确认组件

现在,让我们创建您的表单的最后部分,用户确认他们输入的应用程序的详细信息是正确的。

创建一个 Confirmation.jsx 文件:

1nano src/components/Confirmation.jsx

添加以下代码行:

 1[label src/components/Confirmation.jsx]
 2import React, { Component } from 'react';
 3import { Grid, Header, Segment, Button, List } from 'semantic-ui-react';
 4
 5class Confirmation extends Component {
 6  saveAndContinue = (e) => {
 7    e.preventDefault();
 8    this.props.nextStep();
 9  }
10
11  back = (e) => {
12    e.preventDefault();
13    this.props.prevStep();
14  }
15
16  render() {
17    const { values: { firstName, lastName, email, age, city, country } } = this.props;
18
19    return (
20      <Grid.Column style={{ maxWidth: 450 }}>
21        <Header textAlign='center'>
22          <h1>Confirm your Details</h1>
23
24          <p>Click Confirm if the following details have been correctly entered</p>
25        </Header>
26
27        <Segment>
28          <List divided relaxed>
29            <List.Item>
30              <List.Icon name='users' size='large' />
31              <List.Content>First Name: {firstName}</List.Content>
32            </List.Item>
33
34            <List.Item>
35              <List.Icon name='users' size='large' />
36              <List.Content>Last Name: {lastName}</List.Content>
37            </List.Item>
38
39            <List.Item>
40              <List.Icon name='mail' size='large' />
41              <List.Content>Email: {email}</List.Content>
42            </List.Item>
43
44            <List.Item>
45              <List.Icon name='calendar' size='large' />
46              <List.Content>Age: {age}</List.Content>
47            </List.Item>
48
49            <List.Item>
50              <List.Icon name='marker' size='large' />
51              <List.Content>Location: {city}, {country}</List.Content>
52            </List.Item>
53          </List>
54        </Segment>
55
56        <Segment textAlign='center'>
57          <Button onClick={this.back}>Back</Button>
58
59          <Button onClick={this.saveAndContinue}>Confirm</Button>
60        </Segment>
61      </Grid.Column>
62    )
63  }
64}
65
66export default Confirmation;

这会创建一个部分,显示用户输入的所有细节,并要求他们在提交它们之前确认细节,这通常是你将最终的API调用到后端提交和保存数据的地方。

由于这是一个演示版,所以确认按钮实现了您在以前的组件中使用的相同的保存和继续函数,但是,在现实世界的情况下,您将执行不同的提交函数,以处理最终提交并保存数据。

您的确认组件现在已经完成。

构建成功组件

您项目的下一个和最后的组成部分是成功组成部分,当用户成功保存信息时将返回。

创建一个 Confirmation.jsx 文件:

1nano src/components/Success.jsx

添加以下代码行:

 1[label src/components/Success.jsx]
 2import React, { Component } from 'react';
 3import { Grid, Header } from 'semantic-ui-react';
 4
 5class Success extends Component {
 6  render() {
 7    return (
 8      <Grid.Column style={{ maxWidth: 450 }}>
 9        <Header textAlign='center'>
10          <h1>Details Successfully Saved</h1>
11        </Header>
12      </Grid.Column>
13    )
14  }
15}
16
17export default Success;

这将显示详细信息已成功保存消息,当用户到达表单的最后一步。

您已经完成了您的多步表格的所有组件。

步骤3 - 尝试形式

现在,查看您的Web浏览器中的表格。

使用终端窗口,确保您位于项目目录中. 使用以下命令开始项目:

1npm start

在您的 Web 浏览器中导航到localhost:3000

您的应用程序将显示 步骤 1 - 输入用户详细信息 :

UserDetails Section

输入您的信息并点击 保存和继续 后,您将被引导到** 步骤 2 - 输入个人信息** :

Personal Details Section

输入您的信息并点击 保存和继续 ,您将被引导到** 步骤 3 - 确认您的详细信息** :

Confirmation Section

点击确认后,您将被引导到步骤 4 – 成功

您现在在 React 中有一个工作多步式表格。

结论

多步表格非常好,当您需要将表单分成部分时,它们还可以让您在继续到下一个步骤之前在每个步骤执行表单验证。

使用交换语句来路由步骤之间消除了对路由器的需求,这意味着您可以将表单插入到其他组件中,而无需调整路由。

如果需要,也可以在步骤之间设置 API 调用,这打开了一些新的可能性。

您也可以通过添加状态管理工具(如 [Redux])(https://redux.js.org/)来更好地处理状态。

如果您想了解更多有关React的信息,请查看我们的React主题页面(https://andsky.com/tags/react)以获取练习和编程项目。

Published At
Categories with 技术
Tagged with
comments powered by Disqus