React + Redux - 在表单组件中处理 CRUD 的最佳方式是什么? [英] React + Redux - What's the best way to handle CRUD in a form component?

查看:20
本文介绍了React + Redux - 在表单组件中处理 CRUD 的最佳方式是什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我得到了一个用于创建、读取、更新和删除的表单.我创建了 3 个具有相同形式的组件,但我向它们传递了不同的道具.我得到了 CreateForm.js、ViewForm.js(带有删除按钮的只读)和 UpdateForm.js.

我曾经使用 PHP,所以我总是以一种形式来做这些.

我使用 React 和 Redux 来管理商店.

当我在 CreateForm 组件中时,我将这个道具传递给我的子组件 createForm={true} 以不使用值填充输入并且不禁用它们.在我的 ViewForm 组件中,我传递了这个道具 readonly="readonly".

而且我遇到了另一个问题,即填充了一个值且不可更新的 textarea.用值反应文本区域只读但需要更新

只有一个组件来处理表单的这些不同状态的最佳结构是什么?

您有什么建议、教程、视频、演示要分享吗?

解决方案

我发现了 Redux 表单 包.它做得非常好!

因此,您可以将 ReduxReact-Redux.

首先你必须创建一个表单组件(显然):

从'react'导入React;从'redux-form'导入{ reduxForm };从'../utils/validateContact'导入validateContact;类 ContactForm 扩展 React.Component {使成为() {const { 字段:{name, address, phone}, handleSubmit } = this.props;返回 (<form onSubmit={handleSubmit}><label>名称</label><input type="text" {...name}/>{name.error &&name.touched &&<div>{name.error}</div>}<label>地址</label><input type="text" {...address}/>{address.error &&address.touched &&<div>{address.error}</div>}<label>电话</label><input type="text" {...phone}/>{phone.error &&phone.touched &&<div>{phone.error}</div>}<button onClick={handleSubmit}>提交</button></表单>);}}ContactForm = reduxForm({form: 'contact',//表单的名称和键//窗体状态将被挂载的位置fields: ['name', 'address', 'phone'],//表单中所有字段的列表validate: validateContact//一个同步验证函数})(联系表);导出默认的 ContactForm;

在此之后,您连接处理表单的组件:

从'react'导入React;从'react-redux'导入{连接};从redux-form"导入{初始化};从'./ContactForm.react'导入ContactForm;类 App 扩展了 React.Component {处理提交(数据){console.log('收到提交!', data);this.props.dispatch(initialize('contact', {}));//清除表格}使成为() {返回 (<div id="应用程序"><h1>应用</h1><ContactForm onSubmit={this.handleSubmit.bind(this)}/>

);}}导出默认连接()(应用程序);

并在合并的减速器中添加 redux-form 减速器:

import { combineReducers } from 'redux';从 './app-reducers' 导入 { appReducer };import { reducer as formReducer } from 'redux-form';让reducers = combineReducers({appReducer, form: formReducer//这是表单减速器});导出默认减速器;

验证器模块如下所示:

导出默认函数validateContact(data, props) {常量错误 = {};如果(!数据.名称){errors.name = '必需';}if(data.address && data.address.length > 50) {errors.address = '必须少于 50 个字符';}如果(!数据.电话){errors.phone = '必需';} else if(!/d{3}-d{3}-d{4}/.test(data.phone)) {errors.phone = '电话必须与999-999-9999"形式匹配'}返回错误;}

表单完成后,当你想用一些值填充所有字段时,可以使用initialize函数:

componentWillMount() {this.props.dispatch(初始化('联系',{名称:'测试'}, ['姓名', '地址', '电话']));}

填充表单的另一种方法是设置初始值.

ContactForm = reduxForm({form: 'contact',//表单的名称和键fields: ['name', 'address', 'phone'],//表单中所有字段的列表validate: validateContact//一个同步验证函数},状态=>({初始值:{名称:state.user.name,地址:state.user.address,电话:state.user.phone,},}))(联系表);

如果您有其他方法可以解决此问题,请留言!谢谢.

I got one form who is used to Create, Read, Update and Delete. I created 3 components with the same form but I pass them different props. I got CreateForm.js, ViewForm.js (readonly with the delete button) and UpdateForm.js.

I used to work with PHP, so I always did these in one form.

I use React and Redux to manage the store.

When I'm in the CreateForm component, I pass to my sub-components this props createForm={true} to not fill the inputs with a value and don't disable them. In my ViewForm component, I pass this props readonly="readonly".

And I got another problem with a textarea who is filled with a value and is not updatable. React textarea with value is readonly but need to be updated

What's the best structure to have only one component which handles these different states of the form?

Do you have any advice, tutorials, videos, demos to share?

解决方案

I found the Redux Form package. It does a really good job!

So, you can use Redux with React-Redux.

First you have to create a form component (obviously):

import React from 'react';
import { reduxForm } from 'redux-form';
import validateContact from '../utils/validateContact';

class ContactForm extends React.Component {
  render() {
    const { fields: {name, address, phone}, handleSubmit } = this.props;
    return (
      <form onSubmit={handleSubmit}>
        <label>Name</label>
        <input type="text" {...name}/>
        {name.error && name.touched && <div>{name.error}</div>}

        <label>Address</label>
        <input type="text" {...address} />
        {address.error && address.touched && <div>{address.error}</div>}

        <label>Phone</label>
        <input type="text" {...phone}/>
        {phone.error && phone.touched && <div>{phone.error}</div>}

        <button onClick={handleSubmit}>Submit</button>
      </form>
    );
  }
}

ContactForm = reduxForm({
  form: 'contact',                      // the name of your form and the key to
                                        // where your form's state will be mounted
  fields: ['name', 'address', 'phone'], // a list of all your fields in your form
  validate: validateContact             // a synchronous validation function
})(ContactForm);

export default ContactForm;

After this, you connect the component which handles the form:

import React from 'react';
import { connect } from 'react-redux';
import { initialize } from 'redux-form';
import ContactForm from './ContactForm.react';

class App extends React.Component {

  handleSubmit(data) {
    console.log('Submission received!', data);
    this.props.dispatch(initialize('contact', {})); // clear form
  }

  render() {
    return (
      <div id="app">
        <h1>App</h1>
        <ContactForm onSubmit={this.handleSubmit.bind(this)}/>
      </div>
    );
  }

}

export default connect()(App);

And add the redux-form reducer in your combined reducers:

import { combineReducers } from 'redux';
import { appReducer } from './app-reducers';
import { reducer as formReducer } from 'redux-form';

let reducers = combineReducers({
  appReducer, form: formReducer // this is the form reducer
});

export default reducers;

And the validator module looks like this:

export default function validateContact(data, props) {
  const errors = {};
  if(!data.name) {
    errors.name = 'Required';
  }
  if(data.address && data.address.length > 50) {
    errors.address = 'Must be fewer than 50 characters';
  }
  if(!data.phone) {
    errors.phone = 'Required';
  } else if(!/d{3}-d{3}-d{4}/.test(data.phone)) {
    errors.phone = 'Phone must match the form "999-999-9999"'
  }
  return errors;
}

After the form is completed, when you want to fill all the fields with some values, you can use the initialize function:

componentWillMount() {
  this.props.dispatch(initialize('contact', {
    name: 'test'
  }, ['name', 'address', 'phone']));
}

Another way to populate the forms is to set the initialValues.

ContactForm = reduxForm({
  form: 'contact',                      // the name of your form and the key to
  fields: ['name', 'address', 'phone'], // a list of all your fields in your form
  validate: validateContact             // a synchronous validation function
}, state => ({
  initialValues: {
    name: state.user.name,
    address: state.user.address,
    phone: state.user.phone,
  },
}))(ContactForm);

If you got any other way to handle this, just leave a message! Thank you.

这篇关于React + Redux - 在表单组件中处理 CRUD 的最佳方式是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆