2016-07-29 7 views
0

に反映されていないと私はいくつかの明白な構成が欠けている推測している賢明な私はReduxのアプリを取るされてやろうとしているすべてとmobxを実装する。mobxがオブザーバー

私の問題は、私は店が呼び出されているルート/ユーザー/ 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 

にロードされていないため、ヌル値が原因RETのプレゼンタ自体を爆破されると予想されますそして前に - 私のユーザーは、私は私が台無しに持っているものはよく分からないので、APIを呼び出している店舗機能に@actionを追加したmobx例外

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

に設定されているurned API /約束Iバブルガムとホッジ私はむしろこれを正しく行うにはどのようにいくつかのフィードバックを持っているでしょう修正を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') 
); 

ルート-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

2番目のエラー( 'name'がありません)のために最初のエラーがスローされますが、私は(' @ observable'で囲まれた) 'render'の中で観測値を修正したこれはあなたのコードがやっていることではありません。 – robertklep

+0

私は文脈を正しくしていますか? – maehue

+0

tbh、私はそのために[mobx-connect'](https://github.com/nightwolfz/mobx-connect)を使っています。しかし、 'User'オブザーバブルをオブジェクトで初期化し、ユーザデータを取得するコードをコメントアウトすることで、簡単にテスト可能でなければなりません。 – robertklep

答えて

2

@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; 
     })); 
    } 
+0

私はそれを試みました、それは同じです - それを使用しようとする前に.component/userdetail/presenter.jsの中の値を調べるべきですか?私はプレゼンターのレンダリング方法を

{this.context.store.user.User ? this.context.store.user.User.name : 'nada' }
に変更した場合にのみ動作させることができます - これは最初に 'nada'を点滅させて、ストアが更新された後に正しい値を表示します(APIコールが完了しました) – maehue

+0

正しい動作、完了には未定義の時間がかかりますので、不完全な約束事がない場合でもUIを定義する必要があります。さもなければあなたの約束が満たされるまであなたのUIは「凍結」する必要があります.MobXもReactも奨励したくないシナリオです:) – mweststrate