foxhound87 / mobx-react-form

Reactive MobX Form State Management
https://foxhound87.github.io/mobx-react-form
MIT License
1.09k stars 129 forks source link

cannot pass props to child component #170

Closed mortenko closed 7 years ago

mortenko commented 7 years ago

Hi, I'm trying to implement your mobx-react-form package by myself but I have following issue. I would like to pass props for example form={form.$('product')} defined in NewProductForm.jsx into the component Input defined in Input.jsx.

I checked what I get when I write console.log(props.form) in Input component and it tells me that form.$('product') is empty array and is rendered just this tag <input type="text" />. Probably I'm not passing props correctly but I dont how I can do it in another way.

fields definition in FormFieldConst.jsx

export default {
  fields: {
    product: {
      name: 'productname',
      label: 'productname',
      placeholder: 'write product name',
      rules: 'required|string|between:5,65',
    }
    ....
}

ValidationForm.jsx

const plugins = { dvr: validatorjs };
class ValidateForm extends MobxReactForm {
  onSuccess(form) {
    console.log(form.values());
  }
  onError(form) {
    console.log(form.errors());
  }
}
const validateform = new ValidateForm({ fields, plugins });
export default { validateform };

NewProductForm.jsx

import form from '../components/ValidationForm';

const NewProductForm = () => (
  <form className={styles.newform} onSubmit={form.onSubmit}>
    <Input className="form-input" type="text" form={form.$('product')} />
    <Input className="form-input" type="text" form={form.$('inventory')} />
    <Input className="form-input" type="text" form={form.$('type')} />
    <Input className="form-input" type="text" form={form.$('vendor')} />
    <Button classBtnName="form-button" BtnText="Send Form" />
  </form>
);

export default observer(NewProductForm);

Input.jsx

const Input = props => (
  <div className={props.className}>
    <label htmlFor={props.form.label} >
    </label>
      <input type={props.type} name={props.form.name} value={props.form.name} placeholder={props.form.placeholder} onChange={props.form.sync} />
  </div>
  );
foxhound87 commented 7 years ago

Probably you should change:

export default { validateform };

to

export default validateform;

or just:

export default new ValidateForm({ fields, plugins });

foxhound87 commented 7 years ago

And now I see you are defining the fields as an object, so you should not use the prop name, as it will be set by the object key itself:

   product: { // <-- the key
      name: 'productname', // <-- unnecessary (already set by the key)
      label: 'productname',
      placeholder: 'write product name',
      rules: 'required|string|between:5,65',
    }

but you can use name when you define the fields as a collection with an array.

Eventually, using <Input form={form.$('vendor')} /> could confuse because you are passing the field there, so I would rather use <Input field={form.$('vendor')} />.

mortenko commented 7 years ago

Thanks for you fast response. I did bad export of my fields but anyway I was able to pass down only few properties (label,value,name). When I defined new one for example placeholder, it didn't work. Also, I can't pass down the onChange handler prop. So, I decided to follow more your tutorial and not pass down props to the children component (like Input...). It works now, how I expected.

foxhound87 commented 7 years ago

placeholder is not available as property.

Read the Available Fields Properties on the documentation.

If you want to implement new properties, observables, or methods, you can Extend the Fields Class and the Form Class

Check if your syntax is correct when pass the properties to child components.

Anyway I will write a new tutorial on creating complex forms with nested fields and custom components.

foxhound87 commented 7 years ago

I'm considering to support placeholder as property, since is used very commonly.

foxhound87 commented 7 years ago

Now you can use placeholder. The docs is updated too.

mortenko commented 7 years ago

thanks for your prompt change :). I was bit confused how to extend the fields...maybe you can write an example.

foxhound87 commented 7 years ago

you are welcome! 👍

foxhound87 commented 7 years ago

are you familiar with mobx apis?

foxhound87 commented 7 years ago

I created a dedicated demo repo, and It's updated with custom components.

foxhound87 commented 7 years ago

About extending the forms and fields, I will create a more detailed guide for it.