MobX 本地状态 vs 全局状态
MobX local state vs global state
我正在使用 React 和 mobx 来处理应用程序状态。
我正在使用通过外部存储更改数据的转储组件(ajax 调用、过滤器或映射数组等...)
在表单中,当您必须通过 onChange 事件处理输入更改时,目前我在组件本身内部使用 observable 和 action。
这是一种不好的做法吗?或者我应该把所有的动作和可观察的数据放在一个外部状态中?
如果相反,这种做法是可以接受的,我如何解决必须重置本地可观察状态(如文本输入)以响应在外部存储中执行的 ajax 调用操作的情况?
我可以在动作存储中使用回调来放弃对组件内部动作的控制,如以下示例所示:
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()
})
}
}
是否有其他处理类似案例的最佳做法?
我认为一般的答案是 MobX(或 Redux 就此而言)不是表单状态的正确位置。这有很多原因,但主要是出于性能、复杂性和可维护性方面的考虑。 MobX/Redux 用于全局应用程序状态,而表单状态更本地化。
社区正在转向像 Formik 这样的库,它可以让您在组件本地完全管理表单状态和生命周期。它也适用于 MobX/Redux,可选择初始化全局状态的值。看看,很不错!
即使使用 Mobx,这个答案也不正确。阅读下面的 link 了解更多信息。请参阅“@observer 组件”下的文档。
https://mobx.js.org/refguide/observer-component.html
下面也复制了文字:
Observable local component state
Just like normal classes, you can introduce observable properties on a component by using the @observable decorator. This means that you can have local state in components that doesn't need to be managed by React's verbose and imperative setState mechanism, but is as powerful. The reactive state will be picked up by render but will not explicitly invoke other React lifecycle methods except componentWillUpdate and componentDidUpdate. If you need other React lifecycle methods, just use the normal React state based APIs.
The example above could also have been written as:
import { observer } from "mobx-react"
import { observable } from "mobx"
@observer
class Timer extends React.Component {
@observable secondsPassed = 0
componentWillMount() {
setInterval(() => {
this.secondsPassed++
}, 1000)
}
render() {
return <span>Seconds passed: {this.secondsPassed} </span>
}
}
ReactDOM.render(<Timer />, document.body)
...Observable local state in hook based components
To work with local observable state inside function components, the useLocalStore and useAsObservableSource hooks can be used.
我正在使用 React 和 mobx 来处理应用程序状态。
我正在使用通过外部存储更改数据的转储组件(ajax 调用、过滤器或映射数组等...)
在表单中,当您必须通过 onChange 事件处理输入更改时,目前我在组件本身内部使用 observable 和 action。
这是一种不好的做法吗?或者我应该把所有的动作和可观察的数据放在一个外部状态中?
如果相反,这种做法是可以接受的,我如何解决必须重置本地可观察状态(如文本输入)以响应在外部存储中执行的 ajax 调用操作的情况? 我可以在动作存储中使用回调来放弃对组件内部动作的控制,如以下示例所示:
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()
})
}
}
是否有其他处理类似案例的最佳做法?
我认为一般的答案是 MobX(或 Redux 就此而言)不是表单状态的正确位置。这有很多原因,但主要是出于性能、复杂性和可维护性方面的考虑。 MobX/Redux 用于全局应用程序状态,而表单状态更本地化。
社区正在转向像 Formik 这样的库,它可以让您在组件本地完全管理表单状态和生命周期。它也适用于 MobX/Redux,可选择初始化全局状态的值。看看,很不错!
即使使用 Mobx,这个答案也不正确。阅读下面的 link 了解更多信息。请参阅“@observer 组件”下的文档。
https://mobx.js.org/refguide/observer-component.html
下面也复制了文字:
Observable local component state
Just like normal classes, you can introduce observable properties on a component by using the @observable decorator. This means that you can have local state in components that doesn't need to be managed by React's verbose and imperative setState mechanism, but is as powerful. The reactive state will be picked up by render but will not explicitly invoke other React lifecycle methods except componentWillUpdate and componentDidUpdate. If you need other React lifecycle methods, just use the normal React state based APIs.
The example above could also have been written as:
import { observer } from "mobx-react"
import { observable } from "mobx"
@observer
class Timer extends React.Component {
@observable secondsPassed = 0
componentWillMount() {
setInterval(() => {
this.secondsPassed++
}, 1000)
}
render() {
return <span>Seconds passed: {this.secondsPassed} </span>
}
}
ReactDOM.render(<Timer />, document.body)
...Observable local state in hook based components To work with local observable state inside function components, the useLocalStore and useAsObservableSource hooks can be used.