24

这个问题与Redux Form v6.0.0 相关(在写这个问题时它是 v6.0.0-alpha.15)。

如何从表单组件外部获取表单验证状态(如pristinesubmitting、 )?invalid

让我举个例子。这是“经典的 redux-form”伪结构:

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

...<submit-button>在 JSX 中的位置如下所示:

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

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

  1. 如何从 Redux-Form 外部获取这些pristine, submitting, ?invalid如果可能的话,没有真正讨厌的黑客攻击:-)
  2. 我怎样才能提交该表格?
4

7 回答 7

14

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

提交函数是从父函数定义的,而不是在状态中共享的,因此您可以为每个实例设置不同的函数。

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

export default reduxForm({
    form: 'myFormName'
})(MySubmitForm);
于 2016-09-08T09:31:14.733 回答
4

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

如果“Redux-Form 之外”意味着仍然是 redux 应用程序,您可以尝试通过调度一些操作将这些属性存储在状态中。

在表单中:您正在检测正在发生的事情(当它无效时等),调度一个动作来修改状态,在“外部”部分:您正在将适当的属性传递给组件(与您需要的那些)并取决于您禁用一个按钮。

于 2016-07-06T12:43:02.090 回答
3

在最新的 redux-form 版本 6.0.2 中:

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

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

于 2016-09-05T13:24:01.337 回答
2

现在更容易做到这一点。您可以在具有按钮的独立组件中调用提交操作。

请参阅此示例: https ://redux-form.com/7.1.2/examples/remotesubmit/

于 2017-11-02T23:58:51.897 回答
2

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

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

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

于 2016-07-06T14:15:09.727 回答
1

如果我们只是在讨论提交表单,那么您应该为您的 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]
});

但这种方式似乎有点 hacky,因为据我了解 redux-form API,所有表单状态都不是直接访问的。如果我错了请纠正我

于 2016-08-23T05:11:52.743 回答
0

我最近不得不解决这个问题。我最终将一个回调传递给表单,每次我感兴趣的属性更改时都会调用该回调。我使用componentDidUpdate生命周期方法来检测变化。

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

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

于 2018-06-08T13:55:43.013 回答