如何将基于 React 类的组件转换为功能组件

介绍

胡克在 React v16.8中是稳定的! 胡克提议(https://github.com/reactjs/rfcs/pull/68)是试图解决一些开发人员对React的主要担忧的尝试。 基本上,胡克是一种特殊的功能,允许您插入React功能。 胡克是理想的,如果您以前写过一个功能组件并意识到您需要添加状态。

如果你对Hooks是新手,想要一个概述,请查看我们的React Hooks介绍(https://andsky.com/tech/tutorials/react-hooks)。

useState 声明一个 _state 变量,以便在函数调用之间保留值. 变量被 React 保留. useState 只需要一个参数来初始化您设置的状态值。

在本教程中,您将建立在先前编写的基于类的组件上,并使用useState胡克将其转换为功能组件。

前提条件

本教程已通过 Node v16.4.0, npm v7.20.3, react v17.0.2, react-dom v17.0.2, react-scripts v4.0.3, bootstrap v4.6.0 和 reactstrap v8.9.0 进行验证。

步骤1 - 设置项目

在启动代码中,我们安装了最新版本的reactreact-dom,以及 reactstrap,以帮助我们有一个简单的格式化。

该组件由一个表单组成,其中包含电子邮件密码的字段。

首先,打开您的终端并导航到您的工作目录,然后克隆 Repo:

1git clone https://github.com/do-community/convert-class-to-hook

接下来,导航到新项目目录:

1cd convert-class-to-hook

然后,安装包依赖:

1npm install

花一点时间来熟悉当前位于组件目录中的ClassBasedForm.js组件。

 1[label src/components/ClassBasedForm.js]
 2import React from 'react'
 3import {
 4  Form, FormGroup, Input,
 5  Label, Col, Button,
 6} from 'reactstrap'
 7
 8export default class ClassBasedForm extends React.Component {
 9  constructor(props) {
10    super(props)
11    this.state = {
12      email: '',
13      password: '',
14    }
15    this.handleSubmit = this.handleSubmit.bind(this);
16  }
17
18  handleSubmit(e) {
19    e.preventDefault();
20    console.log(this.state);
21  }
22
23  render() {
24    return (
25      <Form onSubmit={ this.handleSubmit }>
26        <h1>Class-Based Form</h1>
27        <FormGroup row>
28          <Label for="exampleEmail" sm={ 2 }>Email</Label>
29          <Col sm={ 8 }>
30            <Input
31              type="email"
32              name="email"
33              id="exampleEmail"
34              placeholder="email"
35              value={ this.state.email }
36              onChange={ (event) => this.setState({ email: event.target.value }) }
37            />
38          </Col>
39        </FormGroup>
40        <FormGroup row>
41          <Label for="examplePassword" sm={ 2 }>Password</Label>
42          <Col sm={ 8 }>
43            <Input
44              type="password"
45              name="password"
46              id="examplePassword"
47              placeholder="password"
48              value={ this.state.password }
49              onChange={ (event) => this.setState({ password: event.target.value })}
50            />
51          </Col>
52        </FormGroup>
53        <FormGroup check row>
54          <Col sm={ { size: 'auto', offset: 8 } }>
55            <Button>Submit</Button>
56          </Col>
57        </FormGroup>
58      </Form>
59    )
60  }
61};

最后,通过运行应用程序来验证您的安装:

1npm start

在浏览器中打开应用程序. 输入电子邮件和密码的值并提交表单。

Screenshot of the application running in a browser with the class-based component.

在此时,您有一个基于工作类的组件. 在将基于类的组件转换为功能组件时,此行为不应改变。

步骤 2 – 创建一个功能组件

在本节中,您将在组件文件夹中创建一个额外的表单组件,这将是一个FunctionBasedForm.js文件,我们将使用这个组件使用useState链接来构建一个相同的表单。

将基于类的组件和新功能组件并行将使您能够比较这两种实现。

首先,我们将导入 React,并创建一个名为FunctionBasedForm的函数变量,返回一些文本。

 1[label src/components/FunctionBasedForm.js]
 2import React from 'react';
 3
 4const FunctionBasedForm = () => {
 5  return (
 6    <h1>Function Based Form</h1>
 7  )
 8};
 9
10export default FunctionBasedForm;

将此与在ClassBasedForm.js中使用的类 ClassBasedForm 扩展 React.Component {... }声明进行比较。

接下来,您将新组件添加到App.js

目前,请评论以前的ClassBasedForm导入。

输入FunctionBasedForm组件. 在返回声明中,用新的<FunctionBasedForm />组件来替换以前的组件。

 1[label src/App.js]
 2import React, { Component } from 'react';
 3import { Container } from 'reactstrap';
 4// import ClassBasedForm from './components/ClassBasedForm';
 5import FunctionBasedForm from './components/FunctionBasedForm';
 6import Logo from './assets/alligator-logo2.svg';
 7import './App.css';
 8
 9class App extends Component {
10  render() {
11    return (
12      <div className="App">
13        <img src={ Logo } alt="alligator.io logo" width="200" />
14        <Container>
15          <FunctionBasedForm />
16        </Container>
17      </div>
18    );
19  }
20}
21
22export default App;

保存您的更改并运行应用程序,然后访问浏览器中的localhost:3000:

Screenshot of the application running in the browser with the functional component.

应用程序将显示新组件的文本。

步骤 3 – 添加电子邮件密码的状态

在我们的原始ClassBasedForm.js组件中,我们使用构建器初始化我们的状态,我们不再需要在典型的类组件中初始化状态,我们也不需要进行链接!让我们考虑下面的例子。

我们大多数人都熟悉初始化状态,如下:

1constructor(props) {
2  super(props);
3  this.state = {
4    email: '',
5    password: '',
6  };
7}

自从React 16开始,我们不再需要一个建设者,前者变成:

1state = {
2  email: '',
3  password: '',
4};

现在在一个 functional component 中,我们可以使用钩子。我们可以在我们的函数开始时初始化状态和相关设置器. 这可能会为我们消除几行代码。

1const [email, setEmail] = useState('');
2const [password, setPassword] = useState('');

让我们打破上面的一条线。

1const [ email, setEmail] = useState('');
  • const: 创建一个变量为我们的状态和相关的状态变量设置
  • email: 启动并声明我们的第一个变量 email.
  • setEmail: 启动与变量 email 相关的设置函数。

现在,请在代码编辑器中重新参阅FunctionBasedForm.js

从 ClassBasedForm.js 复制代码并删除函数、点击处理器和状态变量。

接下来,将 { useState } 添加到您的 React 导入中,并添加上一节定义的状态变量。

 1[label src/components/FunctionBasedForm.js]
 2import React, { useState } from 'react';
 3import {
 4  Form, FormGroup, Input,
 5  Label, Col, Button,
 6} from 'reactstrap'
 7
 8const FunctionBasedForm = () => {
 9  const [email, setEmail] = useState('');
10  const [password, setPassword] = useState('');
11
12  return (
13    <Form>
14      <h1>Function Based Form</h1>
15      <FormGroup row>
16        <Label for="exampleEmail" sm={ 2 }>Email</Label>
17        <Col sm={ 8 }>
18          <Input
19            type="email"
20            name="email"
21            id="exampleEmail"
22            placeholder="email"
23          />
24        </Col>
25      </FormGroup>
26      <FormGroup row>
27        <Label for="examplePassword" sm={ 2 }>Password</Label>
28        <Col sm={ 8 }>
29          <Input
30            type="password"
31            name="password"
32            id="examplePassword"
33            placeholder="password"
34          />
35        </Col>
36      </FormGroup>
37      <FormGroup check row>
38        <Col sm={ { size: 'auto', offset: 8 } }>
39          <Button>Submit</Button>
40        </Col>
41      </FormGroup>
42    </Form>
43  )
44};
45
46export default FunctionBasedForm;

保存您的更改,并访问您的浏览器中的应用程序。

Screenshot of the application running in the browser with the functional component.

在此时,功能组件视觉上与基于类的组件相同。

步骤 4 — 添加onChangehandleSubmit的功能

现在让我们审查我们的功能来使用Hooks。

让我们重新审视我们如何在基于类的组件中更新状态:

1onChange={ (event) => this.setState({ email: event.target.value })

有了链接,我们不再需要thisthis.setState(),因为我们已经启动了我们的状态变量并附加了设置器。

由于有两个变量,我们将使用一个内线函数来调用我们在useState中启动的设置器为每个输入。

对于电子邮件领域:

1<Input
2  type="email"
3  name="email"
4  id="exampleEmail"
5  placeholder="email"
6  value={ email }
7  onChange={ event => setEmail(event.target.value) }
8/>

对于密码领域:

1<Input
2  type="password"
3  name="password"
4  id="examplePassword"
5  placeholder="password"
6  value={ password }
7  onChange={ event => setPassword(event.target.value) }
8/>

现在让我们重写我们的handleSubmit函数。

以下是该函数之前是如何写的:

1handleSubmit(e) {
2  e.preventDefault();
3  console.log(this.state);
4}

<$>[注] **注:**在React 16中,如果您将此写成箭头函数,则不需要将其绑定到构建器中。

现在我们需要为该函数创建一个const。我们再次阻止默认功能,设置变量,并console.log它们。

1const handleSubmit = e => {
2  e.preventDefault();
3  console.log(email);
4  console.log(password);
5}

现在我们可以将我们的处理提交函数添加到我们的表单中的在提交

以下是你的新功能钩子应该是什么样子:

 1[label src/components/FunctionBasedForm.js]
 2import React, { useState } from 'react'
 3import {
 4  Form, FormGroup, Input,
 5  Label, Col, Button,
 6} from 'reactstrap'
 7
 8const FunctionBasedForm = () => {
 9  const [email, setEmail] = useState('');
10  const [password, setPassword] = useState('');
11
12  const handleSubmit = event => {
13    event.preventDefault();
14    console.log(email);
15    console.log(password);
16  }
17
18  return (
19    <Form onSubmit={ handleSubmit }>
20      <h1>Function Based Form</h1>
21      <FormGroup row>
22        <Label for="exampleEmail" sm={ 2 }>Email</Label>
23        <Col sm={ 8 }>
24          <Input
25            type="email"
26            name="email"
27            id="exampleEmail"
28            placeholder="email"
29            value={ email }
30            onChange={ event => setEmail(event.target.value) }
31          />
32        </Col>
33      </FormGroup>
34      <FormGroup row>
35        <Label for="examplePassword" sm={ 2 }>Password</Label>
36        <Col sm={ 8 }>
37          <Input
38            type="password"
39            name="password"
40            id="examplePassword"
41            placeholder="password"
42            value={ password }
43            onChange={ event => setPassword(event.target.value) }
44          />
45        </Col>
46      </FormGroup>
47      <FormGroup check row>
48        <Col sm={ { size: 'auto', offset: 8 } }>
49          <Button>Submit</Button>
50        </Col>
51      </FormGroup>
52    </Form>
53  )
54};
55
56export default FunctionBasedForm;

保存您的更改,并访问您的浏览器中的应用程序。

将一些值添加到表单中,然后使用提交按钮。打开开发人员工具并显示控制台消息。

结论

在本教程中,您建立了以前编写的基于类的组件,并使用useState胡克将其转换为功能组件。

继续你的学习与 如何在React项目中应用反响钩子

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