首页 文章

Redux-form handleSubmit:如何访问存储状态?

提问于
浏览
24

In a redux-form handleSubmit function, which makes an Ajax call, some properties from the Redux state are needed in the Ajax (e.g. user ID).

如果我想在表单的组件中定义 handleSubmit ,这很容易:只需调用 mapStateToProps 即可传入我需要的内容,并在 handleSubmit 中从 this.props 读取它 .

但是,就像一个好的React-Redux开发人员,我写的是 separate view components and containers ,所以我的视图组件可以很简单,很少或没有行为 . 因此,我想 define handleSubmit in my container .

同样,简单 - redux-form被设置为这样做 . 在 mapDispatchToProps 中定义 onSubmit ,表单将自动调用它 .

哦,等等,在 mapDispatchToProps ,没有办法访问redux状态 .

好的,没问题,我只需要将表格值与 handleSubmit 一起传递给我 .

嗯,等等,使用这种机制不可能将任何数据传递到 handleSubmit !你得到一个参数 values ,并且无法添加另一个参数 .

这留下了以下没有吸引力的替代方案(我可以验证1和2的工作原理):

1 Define a submit handler in the form component, 并从那里调用我自己从mapDispatchToProps传入的自定义提交处理函数 . 这没关系,但要求我的组件知道一些不需要显示表单的redux状态的道具 . (此问题不是redux-form独有的 . )

dumbSubmit(values)
{
  const { mySubmitHandler, user} = this.props;
  mySubmitHandler(values, user);
}

<form onSubmit={ handleSubmit(this.dumbSubmit.bind(this)) }>

或者,更简洁地说,这可以全部组合成箭头函数:

<form onSubmit={ handleSubmit((values)=>{mySubmitHandler(values, this.props.user);}

然后为了使这个处理程序完全不可知,它可以将整个this.props传递回自定义处理程序:

<form onSubmit={ handleSubmit((values)=>{mySubmitHandler(values, this.props);}

2 Define onSubmit in mergeProps 而不是mapDispatchToProps,因此它可以访问stateProps . Dan Abramov recommends against using mergeProps (for performance reasons),所以这似乎不是最理想的 .

function mergeProps(stateProps, dispatchProps, ownProps) {
  const { user } = stateProps.authReducer;
  const { dispatch } = dispatchProps;
  return {
    ...ownProps,
    ...dispatchProps,
    ...stateProps,
     onSubmit: (values) => {
       const { name, description } = values;
       const thing = new Thing(name, description, []);
       dispatch(createNewThing(thing, user.id));
     }
  }

3 Copy the state properties into redux-form fields 未映射到表单组件中的任何输入控件 . 这将确保在传回 handleSubmitvalues 参数中可以访问它们 . 这看起来像是一种黑客攻击 .

必须有更好的方法!

Is there a better way?

3 回答

  • 2

    我找到的最好的方法与你提出的第一个解决方案非常相似 .

    利用redux-form传递的 handleSubmit prop可以采用将用作 onSubmit prop的函数,并使用部分应用程序将所需的任何其他参数传递给 onSubmit .

    行动创造者:

    function updateUser(id, { name, lastname }) { ... }
    

    假设组件获得 onUpdateUser 属性,只将参数直接传递给动作创建者 . 组件也会得到 user ,这是一个具有 id 属性的对象,我们希望将这些属性与字段中的值一起传递给动作创建者 .

    零件

    <form onSubmit={this.props.handleSubmit(this.props.onUpdateUser.bind(null, this.props.user.id))}>
    

    这可以轻松地重写为无状态功能组件,只要您将它们放在动作创建器的左侧,就可以适用于任何数量的参数,并且它不需要任何繁重的工作,只需 bind

  • 1

    After spending time refining this question, option #1 is actually pretty good ,在最后的迭代中(箭头函数将所有道具传递回自定义处理程序) . 它允许组件成为无状态,并且完全不知道它没有称之为合理答案的任何状态 . 我很想听听你的解决方案!


    使用表单组件中的箭头函数定义提交处理程序,并从那里调用我自己从mapDispatchToProps传入的自定义提交处理函数 .

    <form onSubmit={ handleSubmit((values)=>{mySubmitHandler(values, this.props.user);}
    

    然后,为了使这个处理程序完全不可知,将整个this.props传递回自定义处理程序:

    <form onSubmit={ handleSubmit((values)=>{mySubmitHandler(values, this.props);}
    

    如果Submit函数只需要不属于表单的值和道具,我们可以只传回表单不使用的那些道具 . 在无状态组件中,这可能如下所示:

    const Thing_Create = ({ fields: {name, description}, 
        error, 
        handleSubmit, 
        mySubmitHandler, 
        submitting, 
        onCancel, 
        ...otherprops}) => {
    return (
    <div>
      <form onSubmit={ handleSubmit((values)=>{
        mySubmitHandler(values, otherprops);}) }>
    [rest of form definition would go here]
    
  • 12

    我能够通过绑定 this 来解决这个问题 .

    Somewhere in render()

    <MyCustomFormComponent onSubmit={handleSubmit.bind(this)}/>
    

    The handleSumit

    handleSubmit(fields) {
        this.props.onSubmit(fields); //this is properly bound, HURRAY :-)
      }
    

    MapDispatchToProps 对于优秀的开发人员:-)

    const mapDispatchToProps = dispatch => ({
      onSubmit: (fields) =>
        dispatch({type: auth.actionTypes.LOGIN, payload: auth.api.login(fields)})
    });
    

相关问题