2016-07-29 73 views
0

與所有事情反應我試圖做一些簡單的,我猜我缺少一些明顯的配置明智所有我想要做的是採取一個REDX應用程序和實施mobx。mobx與反應存儲沒有反映在觀察員

我的問題是,我試圖去的路線/用戶/ 12345

這家店是被稱爲 - 我正在從API獲取數據回來,但我發現除少數例外,首先是從mobx

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

然後如有些預期null值的主持人,因爲RET的炸燬因爲店裏還沒有在店裏裝

Uncaught TypeError: Cannot read property 'name' of null 

然後本身之前 - 在我的用戶正在設置我已經加入到@Action被調用API,所以我不知道我已經有了搞砸商店功能的mobx例外

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

urned 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(容器?)

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

UPDATE

基本上解決方法是@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> 
+0

第一個錯誤是由於第二個錯誤(缺少'name')而引發的,但是當我(錯誤地)在'render'(它被'@ observable'包裹)修改了一個observable時,我只碰到了第三個錯誤。 ,這不是你的代碼在做什麼。 – robertklep

+0

我正確地處理上下文嗎? – maehue

+0

tbh,我使用['mobx-connect'](https://github.com/nightwolfz/mobx-connect),所以我不能肯定地說。但是,它應該很容易通過初始化用戶可觀察對象並註釋掉提取用戶數據的代碼來測試。 – robertklep

回答

2

注意,下面的代碼不被動作保護:

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

action只有裝飾當前函數,但回調是一種反璞歸真的功能,所以改用:

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

我試過了,它是一樣的 - 是否應該在我嘗試使用它之前檢查.component/userdetail/presenter.js中的值?如果我將演示者渲染方法更改爲

{this.context.store.user.User ? this.context.store.user.User.name : 'nada' }
- 這最初會閃爍'nada',然後在更新存儲後(api調用完成後)顯示正確的值,我只能使其工作。 – maehue

+0

聽起來像正確的行爲,您的承諾將需要花費不確定的時間來完成,所以你應該在沒有完成的承諾的情況下定義你的UI。否則,您的用戶界面需要「凍結」,直到您的承諾滿足,MobX和React都不想鼓勵的情景:) – mweststrate