React特征学习Form数据管理示例详解

目录
  • Form数据管理
  • 重置Form状态
    • form验证
  • 小结

Form数据管理

有时会遇到多个位置需要用户输入的情况,若每个状态都配置state或handler会很繁琐,可以尝试下面的方法

import * as React from 'react';
const LoginForm = () => {
  // 将多个状态合并为对象
  const [state, setState] = React.useState({
    email: '',
    password: '',
  });
  // 通过单个handler统一管理
  const handleChange = (e) => {
    setState({
      ...state,
      [e.target.id]: e.target.value,
    });
  };
  const handleSubmit = (e) => {
    e.preventDefault();
    alert(state.email + ' ' + state.password);
  };
  return (
    <form onSubmit={handleSubmit}>
      <div>
        <label htmlFor="email">Email</label>
        <input
          id="email"
          type="text"
          value={state.email}
          onChange={handleChange}
        />
      </div>
      <div>
        <label htmlFor="password">Password</label>
        <input
          id="password"
          type="password"
          value={state.password}
          onChange={handleChange}
        />
      </div>
      <button type="submit">Submit</button>
    </form>
  );
};
export { LoginForm };

重置Form状态

由于每次用户输入后都需要数据重置回初始状态,可以使用以下方法来预设初始值,并重置Form内容,方便新用户的再次输入

import * as React from 'react';
const LoginForm = () => {
  // 初始
  const [state, setState] = React.useState({
    // 设置初始值
    email: '123@456.com',
    password: '12345',
  });
  const handleChange = (e) => {
    setState({
      ...state,
      [e.target.id]: e.target.value,
    });
  };
  const handleSubmit = (e) => {
    e.preventDefault();
    // 在这里重置状态
    setState({
      email: '',
      password: '',
    });
    alert(state.email + ' ' + state.password);
  };
  return (
    <form onSubmit={handleSubmit}>
      <div>
        <label htmlFor="email">Email</label>
        <input
          id="email"
          type="text"
          value={state.email}
          onChange={handleChange}
        />
      </div>
      <div>
        <label htmlFor="password">Password</label>
        <input
          id="password"
          type="password"
          value={state.password}
          onChange={handleChange}
        />
      </div>
      <button type="submit">Submit</button>
    </form>
  );
};
export { LoginForm };

屏幕显示如下,submit后 Form内容会被重置

也可以考虑设置一个变量来统一管理初始值,方便对状态的查找和维护

import * as React from 'react';
const LoginForm = () => {
  // 定义初始值
  const INITIAL_STATE = {
    email: '',
    password: '',
  };
  const [state, setState] = React.useState(INITIAL_STATE);
  const handleChange = (e) => {
    setState({
      ...state,
      [e.target.id]: e.target.value,
    });
  };
  const handleSubmit = (e) => {
    e.preventDefault();
    // 重置初始值
    setState(INITIAL_STATE);
  };
  return (
    <form onSubmit={handleSubmit}>
      <div>
        <label htmlFor="email">Email</label>
        <input
          id="email"
          type="text"
          value={state.email}
          onChange={handleChange}
        />
      </div>
      <div>
        <label htmlFor="password">Password</label>
        <input
          id="password"
          type="password"
          value={state.password}
          onChange={handleChange}
        />
      </div>
      <button type="submit">Submit</button>
    </form>
  );
};
export { LoginForm };

form验证

验证Form的输入是不可或缺的流程,可参考以下方案

import * as React from 'react';
const LoginForm = () => {
  const INITIAL_STATE = {
    email: '',
    password: '',
  };
  // 设置Validation要求
  const VALIDATION = {
    email: [
      {
        isValid: (value) => !!value,
        message: 'Is required.',
      },
      {
        isValid: (value) => /\S+@\S+\.\S+/.test(value),
        message: 'Needs to be an email.',
      },
    ],
    password: [
      {
        isValid: (value) => !!value,
        message: 'Is required.',
      },
    ],
  };
  // 获取ErrorsFields
  const getErrorState = (state) =>
    Object.keys(state).reduce((acc, key) => {
      if (!VALIDATION[key]) return acc;
      const errorsPerField = VALIDATION[key].map((validation) => ({
          isValid: validation.isValid(state[key]),
          message: validation.message,
        })).filter((errorPerField) => !errorPerField.isValid);
      return { ...acc, [key]: errorsPerField };
    }, {});
  const [state, setState] = React.useState(INITIAL_STATE);
  // 设置错误信息变量
  const errorState = getErrorState(state);
  console.log(errorState);
  const handleChange = (e) => {
    setState({
      ...state,
      [e.target.id]: e.target.value,
    });
  };
  const handleSubmit = (e) => {
    e.preventDefault();
    // 获取错误反馈
    const hasErrors = Object.values(errorFields).flat().length > 0;
    if (hasErrors) return;
    setState(INITIAL_STATE);
  };
  return (
    <form onSubmit={handleSubmit}>
      <div>
        <label htmlFor="email">Email</label>
        <input
          id="email"
          type="text"
          value={state.email}
          onChange={handleChange}
        />
         {/* 显示email错误 */}
        {errorState.email?.length ? (
          <span style={{ color: 'red' }}>
            {errorState.email[0].message}
          </span>
        ) : null}
      </div>
      <div>
        <label htmlFor="password">Password</label>
        <input
          id="password"
          type="password"
          value={state.password}
          onChange={handleChange}
        />
        {/* 显示password错误 */}
        {errorState.password?.length ? (
          <span style={{ color: 'red' }}>
            {errorState.password[0].message}
          </span>
        ) : null}
      </div>
      <button type="submit">Submit</button>
    </form>
  );
};
export { LoginForm };

效果显示如下

小结

到这里完成一个简易的React Login Form, 然而现实中React Form的问题还有很多, 随着学习的深入,会继续探索Form实用的复杂性,更多关于React特征Form数据管理的资料请关注我们其它相关文章!

(0)

相关推荐

  • React特征学习之Form格式示例详解

    目录 Form 样式 React hook Form 样式 首先来看一个简单Form, 式样如下 import * as React from 'react'; const LoginForm = () => { return ( <form> <div> // Notice: 这里要用htmlFor,相当于id <label htmlFor="email">Email</label> <input id="emai

  • React的特征单向数据流学习

    目录 正文 状态 => 视图 事件 => 状态改变 => 视图 正文 React推荐one-way单向数据流,注意只是推荐,并不强制,常见有以下两种情况: 状态 => 视图 事件 => 状态改变 => 视图 状态 => 视图 import React from 'react' const App = () => { //设置状态 const [data, setData] = React.useState('状态 => 视图') return ( &l

  • React特征Form 单向数据流示例详解

    目录 引言 集中状态管理 双向数据流 那为何不选择双向数据流 小结 引言 今天将之前的内容做个系统整理,结合 React Form 案例, 来了解下为何React推荐单向数据流,如果采用双向管理,可能的问题 (关于React Form案例,可参考相关文章 - 学习React的特征(二) - React Form 集中状态管理 首先来看之前的React Form, 若采用单向数据流 import * as React from 'react'; const Useremail = props =>

  • React特征学习Form数据管理示例详解

    目录 Form数据管理 重置Form状态 form验证 小结 Form数据管理 有时会遇到多个位置需要用户输入的情况,若每个状态都配置state或handler会很繁琐,可以尝试下面的方法 import * as React from 'react'; const LoginForm = () => { // 将多个状态合并为对象 const [state, setState] = React.useState({ email: '', password: '', }); // 通过单个hand

  • react编写可编辑标题示例详解

    目录 需求 初始需求 方案设计 方案一 span + contentEditable 思路 代码如下 在这个方案中遇到的问题 存在的问题 方案二 直接用input处理展示和编辑 踩到的坑 需求 因为自己换工作到了新公司,上周入职,以前没有使用过react框架,虽然前面有学习过react,但是并没有实践经验 这个需求最终的效果是和石墨标题修改实现一样的效果 初始需求 文案支持可编辑 用户点击位置即光标定位处 超过50字读的时候,超出部分进行截断 当用户把所有内容删除时,失去焦点时文案设置为 “无文

  • react后台系统最佳实践示例详解

    目录 一.中后台系统的技术栈选型 1. 要做什么 2. 要求 3. 技术栈怎么选 二.hooks时代状态管理库的选型 context redux recoil zustand MobX 三.hooks的使用问题与解决方案 总结 一.中后台系统的技术栈选型 本文主要讲三块内容:中后台系统的技术栈选型.hooks时代状态管理库的选型以及hooks的使用问题与解决方案. 1. 要做什么 我们的目标是搭建一个适用于公司内部中后台系统的前端项目最佳实践. 2. 要求 由于业务需求比较多,一名开发人员需要负

  • react redux及redux持久化示例详解

    目录 一.react-redux 二.redux持久化 一.react-redux react-redux依赖于redux工作. 运行安装命令:npm i react-redux: 使用: 将Provider套在入口组件处,并且将自己的store传进去: import FilmRouter from './FilmRouter/index' import {Provider} from 'react-redux' import store from './FilmRouter/views/red

  • React less 实现纵横柱状图示例详解

    目录 引言 主要设计来源 display 布局 display 布局 动态位置使用绝对定位 style JS 引言 之前的文章,咱们介绍过横向和竖向,具体的内容,请看 React + CSS 绘制横向柱状图 React + CSS 绘制竖状柱状图 这次,结合起来,横向和竖向,一起画 主要设计来源 三个部分 <ul className="vertical"> <li className="vertical_li">100</li>

  • vue全局数据管理示例详解

    目录 记账页面标签页面新增 将API封装到window 用computed计算属性 记账页面标签页面新增 记账页面和标签页面都可以新增标签.可是现在有一个bug.在标签页面新增标签之后,在记账页面不会自动同步,要刷新一下才能同步. 这是因为这两个页面的数据tagList都是分别从tagListModel里fetch的.所以就导致了数据不同步. 解决方案:在更高一层的地方统一去tagListModel里fetch一次,把取出来的设成一个全局的属性,然后分别在两个页面直接使用. 我们选择在main.

  • django模板语法学习之include示例详解

    前言 在很多网站中,基本上的都会有一个开头和一个结尾,在每一个网页中都会显示.相对于这种的来说,在Django中,最好的方法就是使用include的标签,在每一个模板中都加入这个开头和结尾的标签. include标签使用 假如我们有以下模板index.html,代码为: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>

  • React学习笔记之列表渲染示例详解

    前言 本文主要给大家介绍了关于React列表渲染的相关内容,分享出来供大家参考学习,下面话不多说了,来一起看看详细的介绍吧. 示例详解: 列表渲染也很简单,利用map方法返回一个新的渲染列表即可,例如: const numbers = [1, 2, 3, 4, 5]; const listItems = numbers.map((number) => <li>{number}</li> ); ReactDOM.render( <ul>{listItems}<

随机推荐