React + Redux - 在表单组件中处理CRUD的最佳方法是什么?

2022-08-30 04:30:25

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

我曾经使用PHP,所以我总是以一种形式做这些事情。

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

当我在 CreateForm 组件中时,我会将此 props 传递给我的子组件,使其不用值填充输入,也不会禁用它们。在我的ViewForm组件中,我传递了这个道具。createForm={true}readonly="readonly"

我遇到了另一个问题,一个文本区域充满了一个值,并且不可更新。具有值的 React 文本区域是只读的,但需要更新

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

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


答案 1

我找到了 Redux Form 包。它做得很好!

所以,你可以将 ReduxReact-Redux 一起使用

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

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;

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

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);

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

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;

验证器模块如下所示:

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;
}

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

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

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

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);

如果您有任何其他方法来处理此问题,请留言!谢谢。


答案 2

更新:它的2018年,我只会使用Formik(或类似Formik的库)

还有react-redux-formstep-by-step),它似乎用标记声明交换了一些redux-form的javascript(和样板)。它看起来不错,但我还没有使用它。

从自述文件中剪切和粘贴:

import React from 'react';
import { createStore, combineReducers } from 'redux';
import { Provider } from 'react-redux';
import { modelReducer, formReducer } from 'react-redux-form';

import MyForm from './components/my-form-component';

const store = createStore(combineReducers({
  user: modelReducer('user', { name: '' }),
  userForm: formReducer('user')
}));

class App extends React.Component {
  render() {
    return (
      <Provider store={ store }>
        <MyForm />
      </Provider>
    );
  }
}

./components/my-form-component.js

import React from 'react';
import { connect } from 'react-redux';
import { Field, Form } from 'react-redux-form';

class MyForm extends React.Component {
  handleSubmit(val) {
    // Do anything you want with the form value
    console.log(val);
  }

  render() {
    let { user } = this.props;

    return (
      <Form model="user" onSubmit={(val) => this.handleSubmit(val)}>
        <h1>Hello, { user.name }!</h1>
        <Field model="user.name">
          <input type="text" />
        </Field>
        <button>Submit!</button>
      </Form>
    );
  }
}

export default connect(state => ({ user: state.user }))(MyForm);

编辑:比较

react-redux-form 文档提供了与 redux-form 的比较:

https://davidkpiano.github.io/react-redux-form/docs/guides/compare-redux-form.html