Skip to content
This repository has been archived by the owner on Aug 23, 2022. It is now read-only.

Documentation is not clear #675

Closed
skleeschulte opened this issue Feb 20, 2017 · 17 comments
Closed

Documentation is not clear #675

skleeschulte opened this issue Feb 20, 2017 · 17 comments

Comments

@skleeschulte
Copy link

I'm new to react-redux-form and I try to find out if it suits my needs. I had a thorough read of the documentation and tried to set up a form. However a lot of things remain unclear to me:

  • What exactly are the responsibilities of the different reducers (modelReducer, modeled and formReducer)? modeled is only mentioned on the models page.
  • When would I use combineForms vs createForms?
  • How do I access the state of the controls / model in my UI? (E.g. for adding a custom CSS class to an input element when it is touched and is invalid.)
  • What is the purpose of the different keys in the redux store? Especially: What state resides in forms.$form (the "top-level" $form object which is not related to a specific form)?
  • Is it safe / intended to subscribe to the store and access the $form objects directly?
  • Is the following statement true for the current version of the library? "To nest it deep, you must specify where the deep combineForms() reducer will live as a model string in the second argument to combineForms(forms, model)". (source) I ask because it seems to work just fine using combineReducers({ forms: combineForms({ ... }) });.
@davidkpiano
Copy link
Owner

What exactly are the responsibilities of the different reducers (modelReducer, modeled and formReducer)? modeled is only mentioned on the models page.

Don't worry about that - start with just combineForms per the Quick Start guide. The (internal) modelReducer is responsible for updating the model state (e.g., user = { name: 'david' }), and the formReducer is responsible for updating the form state (e.g., user.name.touched = true).

const store = createStore(combineForms({
  user: initialUserState,
}));

When would I use combineForms vs createForms?

combineForms is just like combineReducers in that it creates a single reducer function. If you already have an existing object that you passed into combineReducers, you can use createForms to create an object that can be passed in with your other existing reducers:

const reducer = combineReducers({
  foo: fooReducer,
  bar: barReducer,
  ...createForms({
    user: initialUserState,
    goat: initialGoatState,
  }),
});

How do I access the state of the controls / model in my UI? (E.g. for adding a custom CSS class to an input element when it is touched and is invalid.)

Two ways:

  1. in mapProps in your <Control> component. You have access to fieldValue which gives you everything you need. See the FAQs on custom classNames, for example.
  2. Just connect() your component like you normally would. You'll see, depending on your store state, that all the form/field states are available under e.g., forms.user.name or forms.user.$form for an entire form state.

What is the purpose of the different keys in the redux store? Especially: What state resides in forms.$form (the "top-level" $form object which is not related to a specific form)?

Let's say you have a user object that looks like user: { name: 'david' }. Then:

  • forms.user.$form would represent the entire form state.
  • forms.user.name would represent the field state of user.name. Since it's a simple value (a string) and not a complex one, it's considered a field, not a form.

Is it safe / intended to subscribe to the store and access the $form objects directly?

Yes, you can do that. It's especially useful if you want to do something using the same Redux techniques you would use anywhere else - accessing state from the store.

Is the following statement true for the current version of the library? "To nest it deep, you must specify where the deep combineForms() reducer will live as a model string in the second argument to combineForms(forms, model)". (source) I ask because it seems to work just fine using combineReducers({ forms: combineForms({ ... }) });.

The reason that works is actually because 'forms' is the default location that RRF looks for the forms. For most intents and purposes, specify the model path to be safe.

Hope that helps! I'll link to these answers in the FAQ.

@skleeschulte
Copy link
Author

Wow, thank you for your quick answer!! :)

What exactly are the responsibilities of the different reducers (modelReducer, modeled and formReducer)? modeled is only mentioned on the models page.

Don't worry about that - start with just combineForms per the Quick Start guide. [...]

But then how would I know when and how to use modeled?

What is the purpose of the different keys in the redux store? Especially: What state resides in forms.$form (the "top-level" $form object which is not related to a specific form)?

Let's say you have a user object that looks like user: { name: 'david' }. Then:

  • forms.user.$form would represent the entire form state.
  • forms.user.name would represent the field state of user.name. Since it's a simple value (a string) and not a complex one, it's considered a field, not a form.

Ok, but it is still not clear to me what forms.$form represents. In addition, forms.user.$form seems to contain "dead keys": e.g. forms.user.$form.focus and forms.user.$form.pristine are not updated. (Example). And what is retouched?

Is the following statement true for the current version of the library? "To nest it deep, you must specify where the deep combineForms() reducer will live as a model string in the second argument to combineForms(forms, model)". (source) I ask because it seems to work just fine using combineReducers({ forms: combineForms({ ... }) });.

The reason that works is actually because 'forms' is the default location that RRF looks for the forms. For most intents and purposes, specify the model path to be safe.

For me it looks like it also works with other keys, see this example. Isn't that what combineReducers is all about?

Thanks a lot for your help!

@gkweb
Copy link

gkweb commented Apr 19, 2017

@davidkpiano Is it possible to add this example or something similar to the documentation for custom control validation. I feel an example like this using custom Control validation could benefit others. Thanks for a great product!

Codepen here

Cheers,

G

@davidkpiano
Copy link
Owner

Sure thing, @gkweb - I'll add it.

@bpdons
Copy link

bpdons commented Sep 11, 2017

@davidkpiano. I'd really like to know how I could add the error field validation message as a property to a Control Component? This will allow me to display the error messages inline. I'm using the Material-UI library and the property that I need to pass to the field directly is errorText.
I can use the Error Component to display the specific field message below the textfield, but I really want it inline if possible.

Many thanks for your expertise :)
eg.
<Control model=".email" component={materialUITextField} id="registerUser.firstName" name="firstName" floatingLabelText="First Name" errorText={[error message here if not valid]} validators={{ minLength: minLength(2), }} />

@davidkpiano
Copy link
Owner

@bpdons you can do that in mapProps:

<Control model=".email"
  ...
  mapProps={{
    errorText: ({ touched, validity }) => {
      if (touched && !validity.minLength) {
        return 'Must be at least 2 chars';
      }
    }
  }}
/>

@bpdons
Copy link

bpdons commented Sep 12, 2017

Thanks @davidkpiano for your quick reply. I still can't manage to check the validity with your example.
I've created a Gist of a reduced user-form.js combined with your original example file in GitHub which tries to pass the validation through to an email address Material-UI field component.

I keep getting 'undefined' as the validity type on line 40 when logging to console.

Can you please help with what I'm doing wrong?
https://gist.github.com/bpdons/798785bc459da78054e83ee692697704

Many thanks

@davidkpiano
Copy link
Owner

Can you open a new ticket with that, @bpdons so it doesn't get lost?

@charrison-symfact
Copy link

Is it possible to disable the nested forms from being automatically created?

"Forms can be infinitely nested. You can have a form inside a form inside a form! Any sub-model inside a form that isn't a primitive value, such as an object or array, is considered a form. Its form state is accessed with .$form."

My data model is a structured JSON object (originally xml on the server) and I'm concerned about performance with additional form meta-data at each level.

Thanks!

@davidkpiano
Copy link
Owner

@charrison-symfact That's coming in the next version. Want to open an issue so we can track the enhancement?

@charrison-symfact
Copy link

Excellent ... issue created as "Disable automatic creation of nested forms for sub-models #1001"

@mkokoulin
Copy link

Good day! Tell me, please, how to organize the application architecture if I have 4 routes and each has its own forms. How to initialize objects of the form when you go to the next page?

@davidkpiano
Copy link
Owner

@KokoulinM You can just dispatch actions.load(...) to initialize the forms. Or use <LocalForm>.

@mkokoulin
Copy link

Thanks for the answer to the previous question. I have another question: like for example the blur event to send data to Google Analytics? It is better to write middleware or make custom reducer?For example:

<input type="firstName"
onBlur={() => dispatch(actions.blur('___'))} />

@davidkpiano
Copy link
Owner

That's outside the scope of RRF. Use normal React/Redux patterns to accomplish that.

@bradjabel
Copy link

bradjabel commented Mar 2, 2018

@davidkpiano any response to #675 (comment)?

So far this library looks to be exactly what I need! I am just doing a deep dive to make sure. For example, I don't want to have to specify forms.user.firstName just because the forms reducers are nested under forms in my redux store. It seems to work just fine nested there, with user.firstName when the second option to combineForms is left out. A little more clarification on why it is necessary would be awesome!

@ShruthiKartik
Copy link

I am not able to install react-redux-form . It is showing npm error. Also, my doubt is react-redux-form and redux-form same or different? Please help me with this as I am a beginner in react and redux.

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

8 participants