从Redux表单v6.0.0外部提交按钮

Submit button from outside Redux Form v6.0.0

本文关键字:外部 按钮 提交 v6 Redux 表单      更新时间:2023-09-26

这个问题涉及到Redux Form v6.0.0(在写这个问题的时候是v6.0.0-alpha.15)。

如何从表单组件外部获得表单验证状态(如pristine, submitting, invalid) ?

让我举个例子。这是"classic redux-form"伪结构:

<Form(MyExampleForm)>
    <MyExampleForm>
        <input name="title" ... />
        <submit-button />

…其中<submit-button>在JSX中看起来像这样:

<button type="submit" disabled={pristine || submitting || invalid} >Save</button>

但是在我的应用程序中,我的提交按钮必须在表单之外,放在应用程序的不同位置(比如在应用程序头部,在整个应用程序的顶部)。

  1. 我怎么能得到那些pristine, submitting, invalid从外部的Redux-Form?(没有真正讨厌的黑客,如果可能的话:-))
  2. 我如何提交表单?

只需用相同的表单名称装饰另一个组件,您就可以访问相同的状态变量。你也可以传递它的onSubmit函数从父,并能够提交所有的字段值从你定义他们,因为他们都来自redux状态,而不是当前表单实例的HTML。(这是一种"hacky"的方式,但它感觉正确)

submit函数是从parent中定义的,而不是在状态中共享的,所以你可以在每个实例中使用不同的submit函数。

class MySubmitForm extends React.Component {
    render() {
        return (
            <button
                onClick={this.props.handleSubmit}
            >
                {this.props.pristine ? 'pristine' : 'changed'}
            </button>
        )
    }
}
export default reduxForm({
    form: 'myFormName'
})(MySubmitForm);

Redux -form与React Redux一起工作,使React中的html表单使用Redux来存储其所有状态。

如果"在redux - form之外"意味着仍然是redux应用程序,你可以尝试通过调度一些操作来将这些属性保存在状态中。

在表单中:你正在检测发生了什么(当它无效等),调度一个动作来修改状态,在"outside"部分:你正在传递一个适当的属性给组件(与那些你需要的),并取决于你禁用一个按钮。

最新的redux-form version 6.0.2:

  1. 可以通过选择器访问表单状态pristine, submitting, invalid http://redux-form.com/6.0.2/docs/api/Selectors.md/

  2. 可以导出redux-form操作创建者http://redux-form.com/6.0.2/docs/api/ActionCreators.md/

也许你可以看看redux-forms的实例API。它提供了对装饰性表单组件实例的submit()方法的访问。还有一个pristine布尔属性和一个invalid布尔属性可用(也有一个公开提交属性的请求)。

这里有一个例子:http://redux-form.com/5.3.1/#/examples/submit-from-parent?_k=jgv0m4(例子是5.3.1,但过程类似于v6使用实例API)

基本思想是,通过添加ref="myExampleForm"到您的表单,您可以通过this.refs.myExampleForm传递它。然后您可以检查实例的属性或调用submit()方法(或任何其他公开的方法)。

现在做起来更容易了。您可以在具有该按钮的独立组件中调用Submit操作。

请看下面的例子:https://redux-form.com/7.1.2/examples/remotesubmit/

如果我们谈论的只是提交表单,那么你应该为你的redux connect()函数提供{withRef: true}选项。

考虑有子RowDetail组件的Row组件,该组件的信息应该从Row中保存。

RowDetail在本例中可以这样创建:

import { connect } from 'react-redux';
import { reduxForm } from 'redux-form';
const RowDetailForm = reduxForm({form: 'row-detail-form'})(RowDetail);
export default connect(mapStateToProps, null, null, {withRef: true})(RowDetailForm);
然后,在你的父组件(Row)中,你用ref属性创建你的表单:
<RowDetailForm ref={'rowDetailForm'} .../>  

现在提交很容易:

onSave() {
  this.refs.rowDetailForm.getWrappedInstance().submit();
}

如果我们谈论的是原始和其他表单属性,那么你可以尝试从你的组件的mapStateToProps函数中获取它们。

const rowDetailFormName = 'row-detail-form';
const mapStateToProps = (state) => ({
  rowDetailForm: state.form[rowDetailFormName]
});

但这种方式似乎有点黑客,因为我理解redux-form API的所有形式状态从来没有打算被直接访问。如果我写错了,请指正

我最近不得不处理这个问题。最后,我向表单传递了一个回调,每当我感兴趣的属性发生变化时,就会调用该回调。我使用componentDidUpdate生命周期方法来检测更改。

这应该适用于任何版本的库。

这是一个带有示例代码的帖子- http://nikgrozev.com/2018/06/08/redux-form-with-external-submit-button/