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

How to make component observe on form data? #234

Closed zhaoyi0113 closed 7 years ago

zhaoyi0113 commented 7 years ago

My parent component includes a form data as below:

render() {
    const form = this.form;
    return (
      <div className="pt-dark ">
        <form className="profile-form" onSubmit={form.onSubmit}>
          <div className="profile-input-row">
            <Input field={form.$('alias')}/>
          </div>
          <div className="profile-input-row">
            <Input field={form.$('port')}/>
          </div>

Below is the Input component code:

export default observer(({field}) => (

  <div >
    <label  htmlFor={field.id}>{field.label}</label>
    <div className="input-content">
      <input  {...field.bind()} />
    </div>
  </div>
));

when I change the value of the input, my parent component doesn't got rendered. How can I make my current component listen on the form state change?

foxhound87 commented 7 years ago

Have you decorated the parent component with mobx observer too?

zhaoyi0113 commented 7 years ago

Yes I did that. In my parent component I used @observer like below. Is this the correct way to do with mobx-react-form? This decorator works fine for my mobx store states but it doesn't work with mobx-react-form data state. Do I need to add additional decorator for that?

import {inject, observer, action} from 'mobx-react';

@inject('store')
@observer
export default class Panel extends React.Component {
foxhound87 commented 7 years ago

I don't have the whole picture of your code, can be anything. Your component should be stateless since mobx is handling the state, form what I can see, you can try to pass the form as prop instead using this.form.

zhaoyi0113 commented 7 years ago

I have a global mbox store which my component is connecting to. And now my component need to connect to form state as well. How can I do that? I tried this.form.observe method the call function didn't get call. Is there another way to do the connection?

foxhound87 commented 7 years ago

I think your component is not reacting to the mobx changes, so the field observer will not work even.

zhaoyi0113 commented 7 years ago

Here is my component code. I created the ProfileForm which extends from MobxReactForm on its constructor. Is this wrong?

@observer
export default class Panel extends React.Component {

  constructor(props) {
    super(props);
    this.state = {};
    this.form = new ProfileForm({fields: forms.fields}, {plugins: {dvr: validatorjs}});
    this.form.connect = this._connect;
    this.form.observe({
      path: 'hostRadio',
      key: 'value', // can be any field property
      call: ({form, field, change}) => {
        console.log('xxx')
      },
    });
  }
foxhound87 commented 7 years ago

As you are injecting the store with @inject('store'), try to create the form into the store, then in the component access for example this.props.store.form.

zhaoyi0113 commented 7 years ago

yes I am using @inject('store'). Put form into that store should work but I don't want to do that since the form states are temp values which should not be saved into global store. Is there a way for me to use internal store of the form only inside my component?

foxhound87 commented 7 years ago

So why not creating another store? Then pass it with @inject('store', 'form')

zhaoyi0113 commented 7 years ago

Yup, that should work. Thanks.