简体   繁体   中英

MobX local state vs global state

I'm using React with mobx to handle application state.

I'm using dump components which alter data through the external store (ajax call, filter or map array etc ...)

Instead in forms, when you have to handle input change through onChange event, currently I'm using observable and action inside the component itself.

Is it a bad practice? Or should I put all the actions and observable data inside an external state?

If instead, this practice is acceptable, how can I address the case in which I have to reset a local observable state (like text input) in reaction to ajax call action executed in an external store? Could i use callback in action store to give up the control to an action inside the component, like in the following example:

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

@inject("rootStore")
@observer
class ContactForm extends React.Component {

constructor(props) {
  super(props);
  this.externaStore = this.props.rootStore.contactStore
  this.onChangeInput = this.onChangeInput.bind(this)
}

@observable text = ''

@action
onChangeInput(event) {
  this.text = event.target.value
}

@action
resetForm() {
  this.text = ''
}

render() {
 return (
  <form>
    <div className="form-group">
      <label htmlFor="input-text" className="control-label">Text input: 
      </label>
      <input onChange={this.onChangeInput} type="text" value={this.text} id="input-text" name="input-text" className="form-control" />
   </div>

    <button onClick={() => this.externaStore.submitForm(this.text, this.resetForm)} className="btn btn-danger btn-xs" type="button" title="Aggiungi">
      <i className="fa fa-save"></i> Aggiungi
    </button>
   </form>
  )
 }
}

class ExternalStore {

constructor(rootStore) {
  this.rootStore = rootStore
  this.service = rootStore.service
}

@observable textList = []

@action
submitForm(text, cb) {
  this.service.doAjax('POST', '/api/text', JSON.stringify(text)).then(data => {
   this.textList.push(text)
   cb()
  })
 }
}

Are there another best practice to handle similar cases?

I think the general answer is that MobX (or Redux for that matter) isn't the right place for form state. This is for many reasons, but mainly for performance, complexity and maintainability concerns. MobX/Redux is for global application state, whereas form state is much more local.

The community is moving towards libraries like Formik, that let you fully manage the form state and lifecycle locally within the component. It works well with MobX/Redux too, to optionally initialise the values from global state. Check it out, it's pretty great!

https://github.com/jaredpalmer/formik

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM