Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

form and forms in reducer #1906

Closed
drifterz28 opened this issue Oct 4, 2016 · 14 comments
Closed

form and forms in reducer #1906

drifterz28 opened this issue Oct 4, 2016 · 14 comments

Comments

@drifterz28
Copy link

drifterz28 commented Oct 4, 2016

Reading the docs and building the reducer is listed as form when form collides with the props form from redux-form and gives back "object object" as the form type in the main props.

error
warning.js:36 Warning: Failed prop type: Invalid propformof typeobjectsupplied toForm(Test), expectedstring.

my reducer
const rootReducer = combineReducers({ event, form: formReducer, hold, inventories });

solution
const rootReducer = combineReducers({ event, forms: formReducer, hold, inventories });

http://redux-form.com/6.0.2/docs/api/Reducer.md/
https://github.com/erikras/redux-form/blob/master/src/reduxForm.js#L110

spend some time on this and naming the form to forms in the reducer fixed the issue.

updating the docs should fix this issue. looking into pull request if that is what is observed from others.

sorry if I suck at explaining this issue / observation.

@andi5
Copy link

andi5 commented Oct 12, 2016

Most if not all of the redux-form examples mount the formReducer at form and the docs say it should be done like that.

The warning you pasted looks like the Form component gets wrong properties. May you provide a minimal show-case or at least how you use reduxForm()?

Do you use connect with the form, overwriting form somehow?

@drifterz28
Copy link
Author

drifterz28 commented Oct 13, 2016

Here is my form container
`import React, { Component } from 'react';
import { bindActionCreators } from 'redux';
import { connect } from 'react-redux';
import * as Actions from '../actions';
import { getTotalDue, getSelectedOffers } from '../selectors';
import { reduxForm, propTypes } from 'redux-form';

import GiftCertificate from '../components/gift-certificate.jsx';
import PaymentMethodSelector from '../components/payment-method-selector.jsx';
import EticketInformation from '../components/eticket-information.jsx';
import PurchaseSummary from '../components/purchase-summary.jsx';
import { createOrder } from '../actions/order';

const { func, object, arrayOf } = React.PropTypes;

class CompletePurchase extends Component {

static propTypes = {
...propTypes,
actions: object,
creditCards: arrayOf(object),
handleSubmit: func,
hold: object,
inventories: arrayOf(object),
purchaseInfo: object,
selectedOffers: arrayOf(object)
};
formSubmit = (data) => {
const { hold, inventories, selectedOffers } = this.props;
return createOrder({data, inventories, hold, selectedOffers});
}
render() {
const { actions, creditCards, handleSubmit, purchaseInfo } = this.props;

return (
  <form onSubmit={handleSubmit(this.formSubmit)} className='ck-step-two open' style={{ maxHeight: 'none' }}>
    <GiftCertificate />
    <PaymentMethodSelector
      creditCards={creditCards}
      selectedCard={purchaseInfo.selectedCard}
      onSelectCard={actions.selectCard} />
    <EticketInformation />
    <div className='ck-section-divider'/>
    {purchaseInfo && <PurchaseSummary {...this.props}/>}
  </form>
);

}
}

const completePurchase = reduxForm({
form: 'checkout'
})(CompletePurchase);

export default connect(
state => ({
...state,
subtotal: getTotalDue(state),
selectedOffers: getSelectedOffers(state)
}),
dispatch => ({ actions: bindActionCreators(Actions, createOrder, dispatch) })
)(completePurchase);
`

@andi5
Copy link

andi5 commented Oct 13, 2016

Thank you for posting this complete code sample! By mounting the formReducer at form, redux-form will manage its own state within the form property of the redux store.

This redux store's state is passed to mapStateToProps. You take all these properties, add a few others (like subtotal), and connect it to the form component. But that means that the form property to the form will not be the string you intended, but instead the internal redux-form state object. You cannot connect ...state this way and why should you?

I hope this helped a bit.

@drifterz28
Copy link
Author

helped a bit but I am not sure I follow. so is reduxForm a form a connect and should be treated like one? or does the reduxForm completePurchase need to be added to my state in the connect?

Thanks for the help.

@andi5
Copy link

andi5 commented Oct 13, 2016

I am not sure I understand this question correctly.

Redux-form and connect are similar in that they create higher order components. They enrich the thing they wrap.

By using reduxForm, you can create a form and let redux-form pass form-related properties to your CompletePurchase. You do not need to pass those yourself, especially not something from redux-form state. I'd say you can remove propTypes from CompletePurchase.propTypes and only specify what you need, like handleSubmit.

Now it might be that you need other properties mapped from the redux store state or dispatch. Here you can use connect. The additional properties redux-form does not know about will be forwarded to your own component (if I understand correctly).

Maybe installing the react and redux developer tools for Chrome can visualise this better.

@drifterz28
Copy link
Author

I set this up based off of this example
http://redux-form.com/6.1.0/examples/initializeFromState/

and the only difference to me is that the component is a stateless function.
I have removed ...state from my code and I am still getting 'object object'

so I have the redux and react dev tools and I am still not seeing anything fishy.

@rloomba
Copy link

rloomba commented Oct 13, 2016

@drifterz28 your reducer needs to use the form key

const rootReducer = combineReducers({ event, form: formReducer, hold, inventories });

@drifterz28
Copy link
Author

That was changed back... I should update that, but now it is.

@rloomba
Copy link

rloomba commented Oct 13, 2016

you need to remove ...state from your connect. form is getting passed in that's what causing the problem.

export default connect(
state => ({
subtotal: getTotalDue(state),
selectedOffers: getSelectedOffers(state)
}),

@drifterz28
Copy link
Author

Yeah, I have removed ...state and issue persists.

@rloomba
Copy link

rloomba commented Oct 14, 2016

are you manually passing in a form key in your

export default connect( state => ({ subtotal: getTotalDue(state), selectedOffers: getSelectedOffers(state) }), ?

somewhere you're overriding that form key

@RobIsHere
Copy link

I spent also about one hour on this. Maybe a better hint would be useful?

Like "Did you pass "form" slice from redux state as a prop in? It is overwriting the "form" key property of redux-forms! So remove it in your mapStateToProps or mount the form state at a slice name different from >form<"

This object instead of a string error message is extremly hard to reason about.

@gustavohenke
Copy link
Collaborator

Because this issue saw almost no activity for almost a year, I'm closing it.

@lock
Copy link

lock bot commented Dec 7, 2018

This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.

@lock lock bot locked as resolved and limited conversation to collaborators Dec 7, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants