Javascript

受控组件项目实战:从零开始打造你的第一个React项目

本文主要是介绍受控组件项目实战:从零开始打造你的第一个React项目,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
概述

本文详细介绍了React受控组件的项目实战,从受控组件的基本概念和工作原理开始,逐步深入到创建和处理受控组件的代码示例。通过一个完整的用户注册表单项目,展示了如何在实际项目中应用受控组件,并提供了测试和调试的方法。受控组件项目实战涵盖了从需求分析到部署上线的全过程。

React基础入门
React简介

React 是一个由 Facebook 和社区维护的开源 JavaScript 库,主要用于构建用户界面。React 的核心思想是将复杂的用户界面分解为独立且可重用的组件,通过这些组件的组合来构建复杂的用户界面。React 的主要特点包括高性能、可重用组件以及 JSX 语法。

React 的核心特性包括:

  • 虚拟 DOM:React 使用虚拟 DOM 来提升性能。虚拟 DOM 是一个轻量级的对象模型,它将 DOM 的状态保存在一个 JavaScript 对象中。当组件的状态发生变化时,React 会重新渲染虚拟 DOM,并通过比较新旧虚拟 DOM 来确定需要更新的部分,从而减少对真实 DOM 的直接操作,提高应用性能。

  • 组件化:React 通过组件化思想使开发过程模块化,提高了代码的可复用性。一个 React 应用通常由多个组件组成,每个组件都有自己的逻辑和状态,可以独立开发和测试,然后组合成一个更大的应用。

  • 声明式编程:React 采用声明式编程的方式,开发者只需要描述当前界面的状态,React 会自动处理更新和渲染过程。声明式编程使得代码更易读、易维护。

  • JSX:JSX 是一种类似于 HTML 的语法扩展,用来描述 React 组件的结构。JSX 使得开发者可以更直观地定义组件的结构,并且能直接在 JSX 中嵌入 JavaScript 表达式。
安装React环境

要开始使用 React,需要安装一些必要的工具和库。以下是安装步骤:

  1. 安装 Node.js 和 Yarn

    Node.js 是一个开源的 JavaScript 运行环境,允许在服务器端运行 JavaScript。Yarn 是一个依赖管理工具,用于管理项目中的依赖库。你可以通过以下步骤安装 Node.js 和 Yarn:

    • 访问 Node.js 官方网站(https://nodejs.org/)下载并安装最新版本的 Node.js。
    • 通过以下命令安装 Yarn:

      npm install -g yarn
  2. 创建 React 项目

    使用 Create React App 工具可以快速创建一个新的 React project。首先需要安装 Create React App:

    npm install -g create-react-app

    然后使用 create-react-app 命令创建一个新的 React 项目:

    npx create-react-app my-app
    cd my-app

    以上命令会创建一个新的 React 项目,并安装必要的依赖库。你可以通过以下命令启动开发服务器:

    npm start

    启动后,浏览器会自动打开 localhost:3000 并显示一个默认的 React 应用。

  3. 修改默认项目

    创建项目后,你可以在 src 目录下找到初始的 React 组件目录结构。你可以根据需要修改这些文件。index.js 是应用的入口文件,App.js 是应用的主要组件文件。

    • index.js:

      import React from 'react';
      import ReactDOM from 'react-dom';
      import './index.css';
      import App from './App';
      import reportWebVitals from './reportWebVitals';
      
      ReactDOM.render(
      <React.StrictMode>
       <App />
      </React.StrictMode>,
      document.getElementById('root')
      );
      
      reportWebVitals();
    • App.js:

      import React from 'react';
      import './App.css';
      
      function App() {
      return (
       <div className="App">
         <header className="App-header">
           <p>Hello, world!</p>
         </header>
       </div>
      );
      }
      
      export default App;
创建第一个React组件

在 React 中,组件是构建用户界面的基本单元。组件可以分为两类:

  • 函数组件:简单的函数,接收 props 参数并返回 UI。
  • 类组件:继承自 React.Component 的类,包含 render 方法。

以下是一个简单的函数组件示例:

import React from 'react';

function MyComponent(props) {
  return (
    <div>
      <h1>Hello, {props.name}</h1>
    </div>
  );
}

export default MyComponent;

在这个示例中,MyComponent 函数接收一个 props 参数,返回一个包含 h1 标签的 divprops 是组件的属性,可以传递给组件来传递数据和行为。

使用React组件

App.js 中引入并使用 MyComponent

import React from 'react';
import './App.css';
import MyComponent from './MyComponent';

function App() {
  return (
    <div className="App">
      <MyComponent name="World" />
    </div>
  );
}

export default App;

这里的 MyComponent 接收一个 name 属性,并在组件中使用。

完整组件创建过程

下面是一个完整的组件创建过程,包括引入部分、组件定义、组件使用等。

引入部分

首先,我们需要在组件文件中引入 ReactReactDOM

import React from 'react';
import ReactDOM from 'react-dom';

组件定义

接着,定义组件的逻辑和 UI。在这个示例中,我们将创建一个简单的函数组件 MyComponent

function MyComponent(props) {
  return (
    <div>
      <h1>Hello, {props.name}</h1>
    </div>
  );
}

组件使用

最后,将组件引入到 App.js 文件中并使用:

import React from 'react';
import './App.css';
import MyComponent from './MyComponent';

function App() {
  return (
    <div className="App">
      <MyComponent name="World" />
    </div>
  );
}

export default App;
理解受控组件
什么是受控组件

在 React 中,受控组件是将表单元素(如 <input><textarea><select>)绑定到组件的 state 中的组件。通过这种方式,表单元素的行为由组件的状态决定,而不是由 DOM 元素的状态决定。受控组件提供了更好的状态管理,允许你在 React 中更方便地处理表单逻辑。

受控组件的工作原理

受控组件的工作原理是将表单元素的 value 属性绑定到组件的状态中,同时为每个表单元素添加一个 onChange 事件处理函数,用于更新组件的状态。这样,每次表单元素的值发生变化时,都会触发 onChange 事件,从而更新组件的状态。

示例:简单的受控输入组件

以下是一个简单的受控输入组件:

import React, { useState } from 'react';

function ControlledInput() {
  const [value, setValue] = useState('');

  const handleChange = (event) => {
    setValue(event.target.value);
  };

  return (
    <div>
      <input type="text" value={value} onChange={handleChange} />
      <p>当前输入的内容: {value}</p>
    </div>
  );
}

export default ControlledInput;

在这个示例中,value 状态变量用于跟踪输入框的当前值。handleChange 函数会在输入框的值发生变化时调用,并将新的值设置为状态变量的新值。

处理表单提交

受控组件还可以处理表单提交事件。以下是一个处理表单提交的示例:

import React, { useState } from 'react';

function ControlledForm() {
  const [username, setUsername] = useState('');
  const [password, setPassword] = useState('');

  const handleSubmit = (event) => {
    event.preventDefault();  // 阻止表单的默认提交行为
    console.log('Username:', username);
    console.log('Password:', password);
  };

  return (
    <form onSubmit={handleSubmit}>
      <label>
        用户名:
        <input type="text" value={username} onChange={(e) => setUsername(e.target.value)} />
      </label>
      <br />
      <label>
        密码:
        <input type="password" value={password} onChange={(e) => setPassword(e.target.value)} />
      </label>
      <br />
      <button type="submit">提交</button>
    </form>
  );
}

export default ControlledForm;

在这个示例中,handleSubmit 函数会在表单提交时被调用。通过 event.preventDefault() 阻止默认的表单提交行为,并从状态中获取用户名和密码。

使用受控组件处理表单输入

使用受控组件处理表单输入的主要步骤如下:

  1. 设置状态:定义状态变量来存储表单元素的值。
  2. 处理输入变化:为每个表单元素添加 onChange 事件处理函数,用于更新状态。
  3. 渲染表单元素:在渲染表单元素时,将值绑定到状态变量,并将 onChange 事件处理函数绑定到表单元素上。

示例:受控组件的完整示例

以下是一个完整的受控组件示例,包含输入框和按钮:

import React, { useState } from 'react';

function ControlledComponent() {
  const [inputValue, setInputValue] = useState('');

  const handleChange = (event) => {
    setInputValue(event.target.value);
  };

  const handleSubmit = () => {
    alert(`提交的值: ${inputValue}`);
  };

  return (
    <div>
      <input type="text" value={inputValue} onChange={handleChange} />
      <button onClick={handleSubmit}>提交</button>
    </div>
  );
}

export default ControlledComponent;

在这个示例中,inputValue 状态变量用于跟踪输入框的当前值。handleChange 函数会在输入框的值发生变化时调用,并将新的值设置为状态变量的新值。handleSubmit 函数会在按钮被点击时调用,并显示一个警告框,显示输入框的当前值。

实战项目规划
项目需求分析

在开始编写代码之前,首先需要明确项目的需求。假设我们要开发一个简单的用户注册表单,用户可以输入用户名、密码和电子邮件地址,并点击提交按钮。

  • 功能需求

    • 用户可以输入用户名、密码和电子邮件地址。
    • 用户可以点击提交按钮提交表单。
    • 提交按钮应禁用,直到所有必填字段都填写完毕。
    • 表单提交后,显示一条确认消息。
  • 非功能需求
    • 表单应该有良好的用户交互体验。
    • 提交表单时应该有相应的提示信息。
项目结构设计

在项目开始之前,先设计项目的目录结构。以下是一个简单的目录结构:

my-project/
├── public/
│   └── index.html
├── src/
│   ├── App.js
│   ├── index.js
│   ├── components/
│       └── RegistrationForm.js
├── package.json
├── package-lock.json
└── README.md

目录结构说明

  • public/: 存放静态文件,如 HTML 文件和公共资源文件。
  • src/: 存放源代码文件,如组件文件和入口文件。
  • public/index.html: 主 HTML 文件,包含基本的 HTML 结构。
  • src/App.js: 应用的主组件文件。
  • src/index.js: 应用的入口文件,调用 React 代码。
  • src/components/RegistrationForm.js: 用户注册表单组件文件。
  • README.md: 项目说明文件。
编写受控组件代码
创建受控组件的基本步骤

在 React 中创建受控组件的基本步骤如下:

  1. 设置状态:定义状态变量来存储表单元素的值。
  2. 处理输入变化:为每个表单元素添加 onChange 事件处理函数,用于更新状态。
  3. 渲染表单元素:在渲染表单元素时,将值绑定到状态变量,并将 onChange 事件处理函数绑定到表单元素上。
  4. 处理表单提交:为表单添加 onSubmit 事件处理函数,用于处理表单提交。

示例:受控组件的完整示例

以下是一个完整的受控组件示例,包含输入框和提交按钮:

import React, { useState } from 'react';

function RegistrationForm() {
  const [username, setUsername] = useState('');
  const [password, setPassword] = useState('');
  const [email, setEmail] = useState('');
  const [formIsValid, setFormIsValid] = useState(false);

  const handleChange = (event) => {
    const { name, value } = event.target;
    switch (name) {
      case 'username':
        setUsername(value);
        setFormIsValid(value !== '' && password !== '' && email !== '');
        break;
      case 'password':
        setPassword(value);
        setFormIsValid(value !== '' && username !== '' && email !== '');
        break;
      case 'email':
        setEmail(value);
        setFormIsValid(value !== '' && username !== '' && password !== '');
        break;
      default:
        break;
    }
  };

  const handleSubmit = (event) => {
    event.preventDefault();
    alert('用户注册成功');
  };

  return (
    <form onSubmit={handleSubmit}>
      <label>
        用户名:
        <input
          type="text"
          name="username"
          value={username}
          onChange={handleChange}
          required
        />
      </label>
      <br />
      <label>
        密码:
        <input
          type="password"
          name="password"
          value={password}
          onChange={handleChange}
          required
        />
      </label>
      <br />
      <label>
        电子邮件:
        <input
          type="email"
          name="email"
          value={email}
          onChange={handleChange}
          required
        />
      </label>
      <br />
      <button type="submit" disabled={!formIsValid}>
        提交
      </button>
    </form>
  );
}

export default RegistrationForm;

在这个示例中,usernamepasswordemail 状态变量分别用于跟踪输入框的当前值。handleChange 函数会在输入框的值发生变化时调用,并将新的值设置为状态变量的新值。handleSubmit 函数会在表单提交时被调用,并显示一个警告框,提示用户注册成功。

处理用户输入和状态管理

在上一个示例中,我们已经展示了如何处理输入变化和表单提交。以下是对用户输入和状态管理的更多解释:

  1. 状态变量

    • username:用户名输入框的当前值。
    • password:密码输入框的当前值。
    • email:电子邮件输入框的当前值。
    • formIsValid:表单是否有效(所有输入框都有值)。
  2. 处理输入变化

    • 使用 useState 创建状态变量,并通过 onChange 事件处理函数更新状态。
    • 根据输入框的 name 属性更新相应的状态变量。
    • 根据输入框的值更新 formIsValid 的值。
  3. 渲染表单元素

    • 将输入框的 value 属性绑定到状态变量。
    • onChange 事件处理函数绑定到输入框上。
    • 为提交按钮添加 disabled 属性,根据 formIsValid 的值禁用或启用按钮。
  4. 处理表单提交
    • 使用 onSubmit 事件处理函数阻止表单的默认提交行为。
    • 显示一条确认消息,提示用户注册成功。

示例:处理用户输入和状态管理的详细代码

import React, { useState } from 'react';

function RegistrationForm() {
  const [username, setUsername] = useState('');
  const [password, setPassword] = useState('');
  const [email, setEmail] = useState('');
  const [formIsValid, setFormIsValid] = useState(false);

  const handleChange = (event) => {
    const { name, value } = event.target;
    switch (name) {
      case 'username':
        setUsername(value);
        setFormIsValid(value !== '' && password !== '' && email !== '');
        break;
      case 'password':
        setPassword(value);
        setFormIsValid(value !== '' && username !== '' && email !== '');
        break;
      case 'email':
        setEmail(value);
        setFormIsValid(value !== '' && username !== '' && password !== '');
        break;
      default:
        break;
    }
  };

  const handleSubmit = (event) => {
    event.preventDefault();
    alert('用户注册成功');
  };

  return (
    <form onSubmit={handleSubmit}>
      <label>
        用户名:
        <input
          type="text"
          name="username"
          value={username}
          onChange={handleChange}
          required
        />
      </label>
      <br />
      <label>
        密码:
        <input
          type="password"
          name="password"
          value={password}
          onChange={handleChange}
          required
        />
      </label>
      <br />
      <label>
        电子邮件:
        <input
          type="email"
          name="email"
          value={email}
          onChange={handleChange}
          required
        />
      </label>
      <br />
      <button type="submit" disabled={!formIsValid}>
        提交
      </button>
    </form>
  );
}

export default RegistrationForm;

在这个示例中,handleChange 函数会在每次输入框的值发生变化时更新状态变量,并根据输入框的值更新 formIsValid 的值。handleSubmit 函数会在表单提交时被调用,并显示一个警告框,提示用户注册成功。提交按钮会根据 formIsValid 的值禁用或启用。

测试和调试受控组件
单元测试受控组件

在开发过程中,单元测试是非常重要的。React 提供了多种测试工具,如 Jest 和 React Testing Library,可以用来编写和运行单元测试。

使用 Jest 和 React Testing Library

  1. 安装测试工具

    首先,需要安装 Jest 和 React Testing Library:

    npm install --save-dev jest @testing-library/react @testing-library/jest-dom @testing-library/react-hooks
  2. 编写测试代码

    使用 describeitexpect 等方法编写测试代码。以下是一个简单的测试示例:

    import React from 'react';
    import { render, fireEvent } from '@testing-library/react';
    import RegistrationForm from './RegistrationForm';
    
    test('应验证表单提交', () => {
     const { getByPlaceholderText, getByText } = render(<RegistrationForm />);
     const usernameInput = getByPlaceholderText('用户名');
     const passwordInput = getByPlaceholderText('密码');
     const emailInput = getByPlaceholderText('电子邮件');
     const submitButton = getByText('提交');
    
     fireEvent.change(usernameInput, { target: { value: 'testuser' } });
     fireEvent.change(passwordInput, { target: { value: 'testpassword' } });
     fireEvent.change(emailInput, { target: { value: 'testuser@example.com' } });
    
     fireEvent.click(submitButton);
    
     expect(window.alert).toHaveBeenCalledWith('用户注册成功');
    });

    这个测试代码会渲染 RegistrationForm 组件,获取用户名、密码和电子邮件输入框以及提交按钮,模拟输入和点击事件,并验证 alert 函数是否被正确调用。

  3. 运行测试

    使用以下命令运行测试:

    npm test

示例:测试代码详细说明

以下是一个更详细的测试示例,展示了如何测试受控组件的表单提交:

import React from 'react';
import { render, fireEvent, screen } from '@testing-library/react';
import '@testing-library/jest-dom/extend-expect';
import RegistrationForm from './RegistrationForm';

test('提交表单时应显示确认消息', () => {
  const { getByPlaceholderText, getByText } = render(<RegistrationForm />);
  const usernameInput = getByPlaceholderText('用户名');
  const passwordInput = getByPlaceholderText('密码');
  const emailInput = getByPlaceholderText('电子邮件');
  const submitButton = getByText('提交');

  fireEvent.change(usernameInput, { target: { value: 'testuser' } });
  fireEvent.change(passwordInput, { target: { value: 'testpassword' } });
  fireEvent.change(emailInput, { target: { value: 'testuser@example.com' } });

  fireEvent.click(submitButton);

  expect(screen.getByText('用户注册成功')).toBeInTheDocument();
});

在这个示例中,使用 getByPlaceholderTextgetByText 方法获取输入框和按钮元素,使用 fireEvent.changefireEvent.click 方法模拟输入和点击事件,并使用 expect 方法验证表单提交后是否显示了确认消息。

调试常见问题

在开发过程中,可能会遇到一些常见的调试问题。以下是一些调试技巧:

  1. 检查状态变量

    • 使用 console.log 输出状态变量的值,检查它们是否按预期更新。
  2. 使用 React DevTools

    • React DevTools 是一个浏览器插件,可以帮助你查看组件树、状态和属性。
    • 在 Chrome 或 Firefox 中安装 React DevTools 扩展,打开开发者工具,切换到 React 选项卡,查看组件的状态和属性。
  3. 调试事件处理函数

    • 在事件处理函数中使用 console.log 输出事件对象的值,检查事件是否被正确触发。
  4. 模拟事件
    • 使用 fireEvent 等库提供的模拟事件函数,模拟用户输入和点击事件,帮助调试表单提交逻辑。

示例:调试代码

import React, { useState } from 'react';
import { render, fireEvent, screen } from '@testing-library/react';
import '@testing-library/jest-dom/extend-expect';

function RegistrationForm() {
  const [username, setUsername] = useState('');
  const [password, setPassword] = useState('');
  const [email, setEmail] = useState('');
  const [formIsValid, setFormIsValid] = useState(false);

  const handleChange = (event) => {
    const { name, value } = event.target;
    console.log('handleChange:', name, value);
    switch (name) {
      case 'username':
        setUsername(value);
        setFormIsValid(value !== '' && password !== '' && email !== '');
        break;
      case 'password':
        setPassword(value);
        setFormIsValid(value !== '' && username !== '' && email !== '');
        break;
      case 'email':
        setEmail(value);
        setFormIsValid(value !== '' && username !== '' && password !== '');
        break;
      default:
        break;
    }
  };

  const handleSubmit = (event) => {
    event.preventDefault();
    console.log('handleSubmit:', username, password, email);
    alert('用户注册成功');
  };

  return (
    <form onSubmit={handleSubmit}>
      <label>
        用户名:
        <input
          type="text"
          name="username"
          value={username}
          onChange={handleChange}
          required
        />
      </label>
      <br />
      <label>
        密码:
        <input
          type="password"
          name="password"
          value={password}
          onChange={handleChange}
          required
        />
      </label>
      <br />
      <label>
        电子邮件:
        <input
          type="email"
          name="email"
          value={email}
          onChange={handleChange}
          required
        />
      </label>
      <br />
      <button type="submit" disabled={!formIsValid}>
        提交
      </button>
    </form>
  );
}

export default RegistrationForm;

在这个示例中,handleChangehandleSubmit 函数中都使用了 console.log 输出相关信息,帮助调试组件的状态和行为。

项目部署与上线
构建和打包项目

在开发完成后,需要将项目构建和打包,以便部署到线上服务器。以下是构建和打包项目的步骤:

  1. 构建项目

    使用以下命令构建项目:

    npm run build

    这个命令会执行构建脚本,将项目打包成生产模式。构建完成后,会在 build 目录下生成一个包含所有静态文件的目录。

  2. 打包静态文件

    如果需要将静态文件打包到一个单独的文件夹中,可以使用一些工具进行打包。以下是一个示例命令:

    npm run build && cp -r build/* ./static/

    这个命令会将 build 目录下的所有文件复制到 static 目录中。

示例:构建和打包代码

// package.json
{
  "name": "my-project",
  "version": "1.0.0",
  "main": "index.js",
  "scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build",
    "test": "react-scripts test",
    "eject": "react-scripts eject"
  },
  "eslintConfig": {
    "extends": "react-app"
  },
  "browserslist": {
    "production": [
      ">0.2%",
      "not dead",
      "not op_mini all"
    ],
    "development": [
      "last 1 chrome version",
      "last 1 firefox version",
      "last 1 safari version"
    ]
  },
  "devDependencies": {
    "jest": "27.0.3",
    "@testing-library/react": "12.0.0",
    "@testing-library/jest-dom": "5.14.1",
    "@testing-library/react-hooks": "7.0.1"
  }
}

package.json 文件中定义了 build 脚本,用于构建项目。执行 npm run build 命令会生成生产模式的构建文件。

部署到线上服务器

在构建和打包完成后,需要将生成的文件部署到线上服务器。以下是部署的步骤:

  1. 选择服务器

    选择一个合适的服务器来部署你的应用。常见的服务器选择包括 AWS、Google Cloud、Azure 等。你也可以使用一些云服务商提供的静态网站托管服务,如 Netlify、Vercel 等。

  2. 上传文件

    将构建生成的文件上传到你的服务器。如果使用云服务商提供的静态网站托管服务,可以直接通过界面上传文件。

  3. 配置域名

    如果需要,你可以将域名配置到你的服务器上。大多数云服务商提供域名映射的功能,可以将域名指向你的服务器。

示例:部署代码

假设你使用的是 Netlify 作为静态网站托管服务,以下是如何部署的步骤:

  1. 创建 Netlify 账户

    首先,你需要在 Netlify 上创建一个账户。

  2. 连接 Git 仓库

    在 Netlify 中连接你的 Git 仓库,可以是 GitHub、GitLab、Bitbucket 等。

  3. 选择构建命令

    在 Netlify 项目的设置中,选择适当的构建命令。对于 React 应用,通常使用 npm run build 命令。

  4. 上传文件

    Netlify 会自动上传并构建你的项目,生成的文件会被部署到线上服务器。

示例:Netlify 部署配置

{
  "name": "my-project",
  "description": "我的第一个 React 项目",
  "websiteUrl": "https://myproject.netlify.app",
  "buildCommand": "npm run build",
  "outputDirectory": "build",
  "distDir": "build",
  "framework": "react",
  "builds": [
    {
      "directory": ".",
      "output": "build",
      "public": "build",
      "buildCommand": "npm run build",
      "distribution": "build"
    }
  ],
  "functions": [],
  "redirects": [],
  "headers": [],
  "redirectsFrom": [],
  "redirectsTo": [],
  "domains": [
    {
      "name": "myproject.netlify.app",
      "cname": "myproject.netlify.app",
      "certificate": "auto"
    }
  ],
  "customDomains": [
    {
      "name": "myproject.com",
      "cname": "myproject.com",
      "certificate": "auto"
    }
  ],
  "customHeaders": [],
  "customRedirects": [],
  "customFunctions": [],
  "customRedirectsFrom": [],
  "customRedirectsTo": [],
  "customRedirectsFromPath": [],
  "customRedirectsToPath": [],
  "customRedirectsFromDomain": [],
  "customRedirectsToDomain": [],
  "customRedirectsFromHost": [],
  "customRedirectsToHost": []
}

在 Netlify 中,你可以在项目的设置中配置以上信息,包括构建命令、输出目录、域名等。

这篇关于受控组件项目实战:从零开始打造你的第一个React项目的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!