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

Reactjs 观察者中未反映具有反应存储的mobx,reactjs,mobx,Reactjs,Mobx,正如所有事情一样,我正在尝试做一些简单的事情,我猜我错过了一些明显的配置方面的东西。我正在尝试做的就是使用redux应用程序并实现mobx 我的问题是我试图转到route/user/12345 正在调用存储-我正在从API获取数据,但是我得到了一些异常,第一个是来自mobx An uncaught exception occurred while calculation your computed value, autorun or tranformer. Or inside the rende

正如所有事情一样,我正在尝试做一些简单的事情,我猜我错过了一些明显的配置方面的东西。我正在尝试做的就是使用redux应用程序并实现mobx

我的问题是我试图转到route/user/12345

正在调用存储-我正在从API获取数据,但是我得到了一些异常,第一个是来自mobx

An uncaught exception occurred while calculation your computed value, autorun or tranformer. Or inside the render().... In 'User#.render()'
然后,正如预期的那样,由于存储尚未加载,presenter中出现了一个空值

 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`
我已经在调用api的store函数中添加了@action,所以我不确定自己搞砸了什么——在我修复bubble gum和hodge podge之前,我希望得到一些如何正确操作的反馈。谢谢

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')
);
.component/userdetail/index.js容器

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;
}

并在演示者中包含一个复选框,表明我们确实有东西要显示

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

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

   @action getUser(userId){
      userApi.getUser(userId).then((data) => {
         // not in action
         this.User = data;
      });
   }
该操作仅装饰当前函数,但回调是另一个函数,因此请改用:

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

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

   @action getUser(userId){
      userApi.getUser(userId).then((data) => {
         // not in action
         this.User = data;
      });
   }
该操作仅装饰当前函数,但回调是另一个函数,因此请改用:

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

第一个错误是因为第二个缺少名称而引发的,但我只是在错误地修改了@observable包装的渲染中的observable时遇到了第三个错误,这不是您的代码所做的。我是否正确地处理了上下文?tbh,我使用它,所以我不能确定。但通过使用对象初始化用户observable并注释出获取用户数据的代码,应该可以很容易地对其进行测试。第一个错误是因为第二个错误缺少名称而引发的,但我只是在错误地修改了由@observable包装的渲染中的observable时遇到了第三个错误,这不是你的代码所做的。我做的上下文正确吗?tbh,我用它,所以我不能肯定。但是,通过使用对象初始化用户observable并注释出获取用户数据的代码,应该可以很容易地对其进行测试。我试过了,结果是一样的——在尝试使用它之前,是否应该检查.component/userdetail/presenter.js中的a/值?只有将presenters render方法更改为{this.context.store.user.user?this.context.store.user.user.name:'nada'}时,我才能让它工作-这最初闪烁'nada',然后在存储更新后显示正确的值api调用CompleteTheat听起来像是正确的行为,您的承诺需要一段未定义的时间才能完成,因此您应该在没有未完成承诺的情况下定义UI。否则,您的UI将需要冻结,直到您的承诺得到满足,这是MobX和React都不希望鼓励的场景:我尝试了,结果是一样的-在尝试使用它之前,我是否应该检查.component/userdetail/presenter.js中的a/值?只有将presenters render方法更改为{this.context.store.user.user?this.context.store.user.user.name:'nada'}时,我才能让它工作-这最初闪烁'nada',然后在存储更新后显示正确的值api调用CompleteTheat听起来像是正确的行为,您的承诺需要一段未定义的时间才能完成,因此您应该在没有未完成承诺的情况下定义UI。否则,您的UI将需要冻结,直到您的承诺得到满足,MobX和React都不希望鼓励这种情况:
   @action getUser(userId){
      userApi.getUser(userId).then((data) => {
         // not in action
         this.User = data;
      });
   }
   @action getUser(userId){
      userApi.getUser(userId).then(action("optional name", (data) => {
         // not in action
         this.User = data;
      }));
   }