Closed kolpav closed 8 years ago
Without knowing how your redux state is setup, here are 2 options.
Just use redux state. redux-form passes through your props, so if you track isSubmitting
in your redux state you can just pass that in with your connect higher order component.
// imagine your `login` state looks (something) like this:
{
hasPendingLogin: boolean,
isAuthenticated: boolean,
user: ?Object,
}
// then you can just select that pending login state, since that would be tied to your login action
export default compose(
connect(
state => ({
initialModel: {...},
isSubmitting: state.session.hasPendingLogin,
}), {
onSubmit: login
}
),
reformed()
)(LoginForm)
You could write your isSubmitting
middleware as something like this:
// Note: I wrote this directly in github, so there could easily be a syntax error somewhere
const submittable = (WrappedComponent) => {
return class SubmittableComponent extends React.Component {
state = {
isSubmitting: false,
}
// we assume that `this.props.onSubmit` is a function that returns a
// promise. We can proxy the call to that function so that we can hook
// into the promise to set a loading state.
_onSubmit = (model) => {
this.setState({ isSubmitting: true })
return this.props.onSubmit(model)
.then((res) => {
this.setState({ isSubmitting: false })
return res
})
.catch((err) => {
this.setState({ isSubmitting: false })
throw err // re-throw so anybody handling this sees it fail correctly
})
}
render () {
return React.createElement(WrappedComponent, {
...this.props,
// we proxy `this.props.onSubmit`
onSubmit: this._onSubmit,
isSubmitting: this.state.isSubmitting,
})
}
}
}
Usage:
export default compose(
connect(
state => ({
initialModel: {...},
}), {
onSubmit: login
}
),
submittable, // <---------------
reformed()
)(LoginForm
Note that you could also use this to apply submitError
or submitSuccess
properties as well, if you wanted. The cool thing about this approach is that the only thing your onSubmit
prop must do is return a promise and any form with this wrapper will be able to accurately reflect the submission state.
Personally, if most of my app state was in redux, I'd lean toward the first solution of just leveraging redux for what it's designed to do because you do not want to start duplicating state across the app. If, however, this is not the case, solution #2 means you don't have to worry about creating a bunch of actions and reducers for things that you might not really care about on the global state.
Hope that helps.
What a quick response :smile:
The first approach is what I was doing till now I don't even had to write complicated reducers actions etc.
I only stored name of a form currently being submited
(I don't need to store form values in redux store as my forms are very simple and few so isSubmiting
is only form state I need)
// form reducer //
export const initialState = null
export default handleActions({
[SET_FORM_SUBMITING]: (state, { payload }) => payload,
[CLEAR_FORM_SUBMITING]: () => null
}, initialState)
// selectors //
export const isLoginFormSubmiting = state => state === 'loginForm'
export const isRegisterFormSubmiting = state => state === 'registerForm'
// etc...
The second approach is what I wanted and I was so close to figuring out this myself but I could find a way how to proxy the onSubmit
. Your solution is perfect thank you!
Hello, First of all I want to thank you for such a cool library. I am still trying to wrap my head around it so I was wondering if you could give me advice how would you go about passing
isSubmiting
state into form from HOC with asumption you will always haveonSubmit
prop. I would like to keep myLoginForm
statelessCode example of what I am trying to achieve