具有反应存储的mobx未反映在观察者

时间:2016-07-29 18:17:24

标签: reactjs mobx

正如所有事情的反应一样,我试图做一些简单的事情而且我猜测我错过了一些明显的配置,所有我想要做的就是采用redux应用程序和实施mobx。

我的问题是我试图去路线/ user / 12345

正在调用商店 - 我从API获取数据但我得到一些例外,第一个是来自mobx

An uncaught exception occurred while calculation your computed value, autorun or tranformer. Or inside the render().... In 'User#.render()'

然后,由于存储器尚未加载,因此有些预期会在演示者中引发空值

 Uncaught TypeError: Cannot read property 'name' of null

然后在商店本身因为返回的api / promise我的用户被设置了一个mobx异常

Uncaught(in promise) Error: [mobx] Invariant failed: It is not allowed to create or change state outside an `action`

我已经将@action添加到调用api的商店功能中,所以我不确定我搞砸了什么 - 在我泡泡和躲避住之前我宁愿有一些反馈如何正确地做到这一点。感谢。

UserStore.js

import userApi from '../api/userApi';
import {action, observable} from 'mobx';

class UserStore{
   @observable User = null;

   @action getUser(userId){
      userApi.getUser(userId).then((data) => {
         this.User = data;
      });
   }
}

const userStore = new UserStore();
export default userStore;
export{UserStore};

index.js

import {Router, browserHistory} from 'react-router;
import {useStrict} from 'mobx';
import routes from './routes-mob';

useStrict(true);
ReactDOM.render(
    <Router history={browserHistory} routes={routes}></Router>,
    document.getElementById('app')
);

路由-mob.js

import React from 'react';
import {Route,IndexRoute} from 'react-router';
import App from './components/MobApp';
import UserDetail from './components/userdetail;

export default(
    <Route name="root" path="/" component={App}>
       <Route name="user" path="user/:id" component={UserDetail} />
    </Route>
);

MobApp.js

import React,{ Component } from 'react';
import UserStore from '../mob-stores/UserStore';

export default class App extends Component{
   static contextTypes = {
      router: React.PropTypes.object.isRequired
   };

   static childContextTypes = {
      store: React.PropTypes.object
   };

   getChildContext(){
      return {
         store: {
            user: UserStore
         }
      }
   }

   render(){
      return this.props.children;
   }

}

.component / userdetail / index.js(container?)

import React, {Component} from 'react';
import userStore from '../../mob-stores/UserStore';
import User from './presenter';

class UserContainer extends Component{
   static childContextTypes = {
       store: React.PropTypes.object
   };

   getChildContext(){
      return {store: {user: userStore}}
   }

   componentWillMount(){
      if(this.props.params.id){
         userStore.getUser(this.props.params.id);
      }
   }

   render(){
      return(<User />)
   }
}

export default UserContainer;

.component / userdetail / presenter.js

import React, {Component} from 'react';
import {observer} from 'mobx-react';

@observer
class User extends Component{
   static contextTypes = {
      store: React.PropTypes.object.isRequired
   }

   render(){
      const {user} = this.context.store;
      return(
          <div>{user.User.name}</div>
      )
   }
}

请原谅我,如果它有点混乱我已经拼凑起来如何从各种博客文章和文档和堆栈溢出问题实现mobx。我很难找到一个不仅仅是标准todoapp的汤到坚果的例子

更新

基本上,修复是@mweststrate回答的组合,下面将动作添加到承诺回复

@action getUser(userId){
  userApi.getUser(userId).then(action("optional name", (data) => {
     // not in action
     this.User = data;
  }));

}

并在演示者中检查我们实际上有什么要显示

<div>{this.context.store.user.User ? this.context.store.user.User.name : 'nada' }</div>

1 个答案:

答案 0 :(得分:4)

请注意,以下代码不受操作保护:

   @action getUser(userId){
      userApi.getUser(userId).then((data) => {
         // not in action
         this.User = data;
      });
   }

action仅修饰当前函数,但回调是一个nother函数,所以改为使用:

   @action getUser(userId){
      userApi.getUser(userId).then(action("optional name", (data) => {
         // not in action
         this.User = data;
      }));
   }