you react pass must handlesubmit form reactjs redux react-redux redux-form

reactjs - react - Redux-form handleSubmit: ¿Cómo acceder al estado de la tienda?



handlesubmit redux form (3)

La mejor manera que encontré es bastante similar a la primera solución que se te ocurrió.

Aproveche el hecho de que la propiedad handleSubmit pasa por redux-form puede tomar una función que se usará como la propiedad onSubmit , y use la aplicación parcial para pasar cualquier otro parámetro que necesite para onSubmit .

Creador de accion:

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

Supongamos que el componente obtiene una propiedad onUpdateUser que simplemente pasa los parámetros directamente al creador de la acción. Y el componente también obtiene user , un objeto con la propiedad id que queremos pasar al creador de acciones junto con los valores en los campos.

Componente

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

Esto se puede volver a escribir fácilmente para los componentes funcionales sin estado, puede funcionar para cualquier cantidad de parámetros siempre que los coloques a la izquierda en el creador de la acción, y no necesite ningún trabajo pesado, simplemente bind

En una función handleSubmit redux-form, que realiza una llamada Ajax, se necesitan algunas propiedades del estado Redux en el Ajax (por ejemplo, ID de usuario).

Esto sería bastante fácil si quisiera definir handleSubmit en el componente del formulario: solo llame a mapStateToProps para pasar todo lo que necesite y this.props desde this.props en mi handleSubmit .

Sin embargo, al igual que un buen desarrollador React-Redux, escribo componentes y contenedores de vista por separado , por lo que mis componentes de vista pueden ser simples con poco o ningún comportamiento. Por lo tanto, quiero definir handleSubmit en mi contenedor .

Una vez más, simple - redux-form está configurado para hacer eso. Defina un onSubmit en mapDispatchToProps , y el formulario lo llamará automáticamente.

Excepto, oh, espera, en mapDispatchToProps no hay manera de acceder al estado de redux.

De acuerdo, no hay problema, solo pasaré los accesorios que necesito a handleSubmit junto con los valores del formulario.

Hmm, espere, ¡es imposible pasar datos a handleSubmit usando este mecanismo! Obtiene un parámetro, values , y no hay manera de agregar otro parámetro.

Esto deja las siguientes alternativas poco atractivas (de las cuales puedo verificar que funcionan 1 y 2):

1 Defina un controlador de envío en el componente de formulario y , desde allí, llame a mi propia función de controlador de envío personalizada que se pasa desde mapDispatchToProps. Esto está bien, pero requiere que mi componente sepa algunas propiedades del estado de redux que no son necesarias para mostrar el formulario. (Este problema no es exclusivo de redux-form.)

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

O, más concisamente, todo esto se puede combinar en una función de flecha:

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

Luego, para hacer que este manejador sea completamente agnóstico, podría pasar todo this.props de vuelta al manejador personalizado:

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

2 Defina onSubmit en mergeProps en lugar de mapDispatchToProps, para que tenga acceso a stateProps. Dan Abramov recomienda no usar mergeProps (por razones de rendimiento) , por lo que parece subóptimo.

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 Copie las propiedades de estado en los campos de formulario de redux que no están asignados a ningún control de entrada en el componente de formulario. Esto asegurará que sean accesibles en el parámetro de values pasado a handleSubmit . Esto parece una especie de hackeo.

¡Tiene que haber una mejor manera!

¿Hay alguna manera mejor?


Pude resolver este problema uniéndolo.

En algún lugar en render ()

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

El mangoSumit

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

MapDispatchToProps para buenos desarrolladores :-)

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


Después de dedicar tiempo a refinar esta pregunta, la opción # 1 es bastante buena , en la iteración final (función de flecha que pasa todos los accesorios al controlador personalizado). Permite que el componente sea sin estado y completamente ignorante de cualquier estado que no consuma. Así que voy a llamar a eso una respuesta razonable. ¡Me encantaría escuchar tus mejores soluciones!

Defina un controlador de envío utilizando una función de flecha en el componente de formulario y, desde allí, llame a mi propia función de controlador de envío personalizada que se pasa desde mapDispatchToProps.

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

Luego, para hacer que este controlador sea completamente agnóstico, devuelva todo this.props al controlador personalizado:

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

Si la función Enviar solo necesita los valores y los accesorios que no formaban parte del formulario, podemos devolver solo aquellos que el formulario no usa. En un componente sin estado, esto podría parecer:

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]