Redux-form handleSubmit: How to access store state?

淺唱寂寞╮ 提交于 2019-11-28 20:17:46

After spending time refining this question, option #1 is actually pretty good, in the final iteration (arrow function that passes all props back to the custom handler). It allows the component to be stateless and completely ignorant of any state that it doesn't consume. So I'm going to call that a reasonable answer. I would love to hear your better solutions!


Define a submit handler using an arrow function in the form component, and from there call my own custom submit handler function passed in from mapDispatchToProps.

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

Then to make this handler completely agnostic, pass the entire this.props back to the custom handler:

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

If the Submit function only needs the values and the props that weren't part of the form, we can pass back just those props which the form doesn't use. In a stateless component, this might look like:

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]

The best way I found is pretty similar to the first solution you came up with.

Take advantage of the fact that the handleSubmit prop passed by redux-form can take a function that will be used as the onSubmit prop, and use partial application to pass any other parameters you need to onSubmit.

Action creator:

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

Suppose the component gets an onUpdateUser property that just passes the parameters straight to the action creator. And the component also gets user, an object with the id property that we want to pass to the action creator along with the values in the fields.

Component

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

This can easily be re-written for stateless functional components, can work for any amount of parameters as long as you place them on the left in the action creator, and it doesn't need any heavy lifting, just bind

I was able to solve this issue by binding this.

Somewhere in render()

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

The handleSumit

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

MapDispatchToProps for good developers :-)

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

This is a variation of @stone's answer, but you can break down option 1 via functional programming:

const mySubmitHandler = props => values => { /* ...code here */ }

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

In this case, mySubmitHandler will return a function taking only one argument that has already closed over this.props, so there's no need to explicitly mention the values argument that handleSubmit is passing.

You could perform the currying of mySubmitHandler in a better and more readable way through ramda.

import { curry } from 'ramda';

const mySubmitHandler = curry((props, values) => { /* ...code here */ });

You can go one step further by composing handleSubmit and mySubmitHandler

import { compose, curry } from 'ramda';

const handleSubmit = values => { /* ...code here */ };
const mySubmitHandler = curry((props, values) => { /* ...code here */ });
const onSubmit = compose(handleSubmit, mySubmitHandler);

<form onSubmit={ onSubmit(this.props) }>

Note that onSubmit(this.props) returns a function that takes one argument (values) and has closed over this.props, creating a function that has access to all the properties it needs!

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!