嗨,我在商店中使用MobX,当计算值发生变化时,我需要进行异步反应:
class Store {
@observable user;
@observable something;
@computed get firstParam () {
return this.user && this.user.params[0];
}
async loadSomething () {
reaction(
() => this.firstParam,
async (param) => {
const { data: something } = await axios.get(`url/${param}`);
runInAction('update state after fetching something', () => {
this.something = something;
});
}
);
}
}
Run Code Online (Sandbox Code Playgroud)
我想知道使用when而不是reaction分开运行条件会有什么区别?
when(
() => !!this.firstParam,
async () => {
// fetch using this.firstParam
}
)
Run Code Online (Sandbox Code Playgroud) 我有一个可观察的对象,我想存储一些数据.密钥是我的客户实体的唯一ID,值是客户订单的数组(对象本身).
我初始化一个对象:
@observable data = {};
Run Code Online (Sandbox Code Playgroud)
然后,当我从网络获取数据时,我想存储它们,使用:
@action
saveData(customerId, ordersForCustomer) {
this.data = extendObservable(this.data, {
[customerId]: observable(ordersForCustomer);
}
}
Run Code Online (Sandbox Code Playgroud)
不幸的是,似乎我的对象(或其属性)没有被监视.
为什么是这样?我该如何解决这个问题?对于可观察对象如何使用数组作为其值,我需要了解一些特殊内容吗?
在MobX中,如何在不重新设置每个值的情况下为整个可观察数组设置新值?
首先想到的是:
let arr = observable([]);
autorun(() => {
console.log('my array changed!');
});
arr = ['foo', 'bar'];
Run Code Online (Sandbox Code Playgroud)
但那不会解雇autorun,我会删除我的observable array并用新的值/数组替换它.
那么,这样做的正确方法是什么?
我此解决方案是使用另一个变量与一个设置器,和内侧setter函数改变观察的阵列索引由索引,置换,添加和删除的索引.像这样:
const {observable, computed, extendObservable} = mobx;
const {observer} = mobxReact;
const {Component} = React;
const {render} = ReactDOM
const {autorun} = mobx
class Store {
@observable entries = [1,2,3,4,5];
set rows(arr) {
// add new values
for (let i = 0, l = arr.length; …Run Code Online (Sandbox Code Playgroud) 我使用一个简单的输入字段,它应该由@observable 值控制:
<div>
<input value={this.props.appState.myValue} onChange={this.handleChange}/>
value: {this.props.appState.myValue}
</div>
Run Code Online (Sandbox Code Playgroud)
将 myValue 更新为 undefined 后,显示值发生变化,但输入字段中的值保持不变。
初始状态:
[initial]
value: initial
Run Code Online (Sandbox Code Playgroud)
更新后:
[initial]
value:
Run Code Online (Sandbox Code Playgroud) 检索数据并设置obseravble数组,这里的代码如下:
import {observable} from 'mobx';
export interface IMenuModel{
Id:number
itemName:string;
parentId?:number;
}
class MenuRepo {
@observable menuItems? : IMenuModel[];
constructor(){
}
getItems():void {
fetch(`..`).then((response: Response): Promise<{ value:IMenuModel[] }> => {
return response.json();
})
.then((response: { value: IMenuModel[] }) : void => {
this.menuItems = response.value;
}, (error: any): void => {
//exception handling
});
}
}
var menuCodes = new MenuRepo
export default menuCodes;
Run Code Online (Sandbox Code Playgroud)
这是观察者阶级;
import * as React from 'react';
import {observer} from 'mobx-react';
import {IMenuModel} from './Codes';
@observer …Run Code Online (Sandbox Code Playgroud) 如何从MobX访问组件引用,下面的示例,运行'doSomething'的乐趣是在componentDidMount之后,我得到的不是函数错误,我想弄清楚如何在MobX中访问ref.什么都会欣赏.非常感谢.
@observer
class MyNav extends Component {
testFun() {
}
}
@observer
class MyComponent extends Component {
doSometing() {
this._myNav.testFun();//this._myNav.testFun() is not a function
}
render() {
return (<MyNav ref={(ref) => this._myNav = ref}/>)
}
}
Run Code Online (Sandbox Code Playgroud) 我对如何在代码中使用@action感到困惑。
class Items {
@observable items= [];
@action addItem() {
let newItem= new Item();
items.push(newItem);
}
}
@observer
class ItemPage extends Component {
constructor() {
super();
}
render() {
const {addItem} = this.props.store;
return (
<div className="items">
<input type="button" value="add" onClick={addItem}/>
</div>
)
}
}
const store = new Items();
Run Code Online (Sandbox Code Playgroud) 我正在将mobX用于我的本地反应项目。请考虑以下商店类别:
class Birds {
@observable listOne = [];
@observable fetchingListOne = false;
@observable fetchErrorOne = '';
@action setListOne = () => {
this.fetchingListOne = true;
api.getList()
.then((data) => {
this.listOne.replace(data);
this.fetchingListOne = false;
})
.catch((error) => {
this.fetchingListOne = false;
this.fetchErrorOne = error;
});
};
}
Run Code Online (Sandbox Code Playgroud)
这是反应成分:
@inject('BirdStore') @observer
export default class Flat extends React.Component {
componentDidMount() {
this.props.BirdStore.setListOne();
}
_renderHeader = () => {
return <Text style={styles.listHeaderText}>
Hello {this.props.BirdStore.listOne.length} is {this.props.BirdStore.fetchingListOne.toString()}
</Text>;
};
_renderItem = ({item}) => …Run Code Online (Sandbox Code Playgroud) 我收到以下错误:
proxyConsole.js:54 Error: [mobx] Invariant failed: Since strict-mode is enabled, changing observed observable values outside actions is not allowed. Please wrap the code in an `action` if this change is intended. Tried to modify: ObservableObject@1.items
at invariant (mobx.module.js:2326)
at fail (mobx.module.js:2321)
at checkIfStateModificationsAreAllowed (mobx.module.js:2890)
at ObservableValue../node_modules/mobx/lib/mobx.module.js.ObservableValue.prepareNewValue (mobx.module.js:796)
at setPropertyValue (mobx.module.js:1673)
at Object.set [as items] (mobx.module.js:1641)
at Store.js:41
at <anonymous>
Run Code Online (Sandbox Code Playgroud)
但是我正在将函数包装起来,action所以我有点困惑:
import { observable, useStrict, action } from 'mobx';
import Services from './Services';
// ...
getAllTodos: action(() => { …Run Code Online (Sandbox Code Playgroud) 我试图mobx用我的React 360制作一个vr应用程序。我尝试使用装饰器语法,但是在浪费大量时间尝试实现它之后,我决定使用nondecorator语法。这是我遇到问题的mobx文档中遇到的一个示例。这是代码:
import {observer} from "mobx-react";
var timerData = observable({
secondsPassed: 0
});
setInterval(() => {
timerData.secondsPassed++;
}, 1000);
@observer class Timer extends React.Component {
render() {
return (<span>Seconds passed: { this.props.timerData.secondsPassed } </span> )
}
};
ReactDOM.render(<Timer timerData={timerData} />, document.body);
Run Code Online (Sandbox Code Playgroud)
注意类observer上的声明Timer。文档指出了这一点。
请注意,使用@observer作为装饰器是可选的,observer(class Timer ... {})实现的效果完全相同。
这是实现的正确方法Timer吗?
observer(class Timer extends React.Component {
render() {
return (<span>Seconds passed: { this.props.timerData.secondsPassed } </span> )
}
})
Run Code Online (Sandbox Code Playgroud) mobx ×10
javascript ×7
reactjs ×7
mobx-react ×5
react-native ×2
arrays ×1
asynchronous ×1
ecmascript-6 ×1
observable ×1
store ×1
typescript ×1