2017-11-16 26 views
0

まず、私はReact developerを経験していません。ちょうどあなたに知らせてください。私は私のレイアウトのコンポーネントまたは_document.js(私は次を使用してプロバイダ経由店を渡すことができMobX + Reactが私を怒らせる

import {observable, action, reaction, computed, autorun} from 'mobx'; 
import scrollTo from 'react-scroll-to-component' 

クラスActivePostsStore {

@observable _posts = new Map() 
    @observable _visiblePosts = new Set() 

    @computed get visiblePosts() { 
    return this._visiblePosts 
    } 

    @action 
    addPost(uuid, ref) { 
    // console.log('add post') 
    this._posts.set(uuid, ref) 
    } 

    @action 
    scrollToPost(uuid) { 
    // console.log('scroll to post') 
    scrollTo(this._posts.get(uuid), {}) 
    } 

    @action 
    addVisiblePost(uuid) { 
    console.log('add vis post', this._visiblePosts.values()) 
    this._visiblePosts.add(uuid) 
    } 

    @action 
    removeVisiblePost(uuid) { 
    console.log('rem vis post', this._visiblePosts.values()) 
    this._visiblePosts = new Set([...this._visiblePosts].filter(el => el !== uuid)) 
    } 

    // reacts = reaction(() => this._visiblePosts,() => console.log('====')) 
    // reactToVisiblePosts() { 
    // 
    // } 
} 


const store = new ActivePostsStore() 
export default store 

私の最初の問題は、:

は、私が店を持っています。 js)。

/*Doesn't work. In root layout*/ 
<Provider store={ActivePostsStore}> 
    <Content /> 
</Provider> 

私が使用しようとするたびにProvider私は自分の店を定義していません。 RootLayoutまたは_document.jsでも。確かに、店舗を利用するコンポーネントのために@observer注釈を提供しました。しかし、ストアは未定義です。

次に、私は@inject('activePostsStore')の結果を使用しようとしました。エラーです。それは、まったく店を提供していないようです。しかし、実際には、私はしました。

だから!

@inject(() => ({ 
    store: ActivePostsStore 
})) 
@observer 

最後に、私は(私はそれをログ)visiblePostsのための要素を追加または削除するためにアクションを使用することができます。私は直接のようにそれを注入することを決めました。しかし!店舗の状態を変更した場合、店舗の小道具はまったく反応しません。たとえば、visiblePostsに新しいエントリを追加することには反応しません。または、ページをリロードすると、定義されていないこともあります。コンポーネントのコードは次のとおりです。

render() { 
    const {classes} = this.props 
    return (
     <div className={classNames(classes.postsTree)}> 
     {this.props.store.visiblePosts} 
     {this.state.groupedDates !== undefined && this.state.groupedDates.map(([date, posts], index) => 
      <PostsTreeGroup 
      active={_.some(posts.map(([uuid]) => uuid), uuid => this.props.store.visiblePosts.has(uuid))} 
      key={date} 
      date={date} 
      posts={posts}/> 
     )} 
     </div> 
    ) 
    } 

誰かが私に物事を働かせるように手伝ってください。

答えて

3

Question1:あなたは店がその小道具に表示するコンポーネント、上の注入を呼び出すとき

プロバイダのみ動作します。したがって、注入を呼び出す必要があります。それ以外の場合、ストアは未定義です(誰もストアのコンポーネントのプロパティを設定しないため)。

注入するために渡す文字列は、プロバイダで指定したプロパティ名と正確に一致する必要があります。

あなたが持っている:

<Provider store={ActivePostsStore}> // store is the property name 

だからあなたも

@inject('store') 

を呼び出す必要が続いてmobxは、キーストアを探し、あなたのプロバイダでそれを見つけ、あなたのコンポーネントに割り当てます。

Question2:

あなたはお店ではなく、他の方法ラウンドで、あなたの目に見えるの記事を計算します。 したがって、メソッドvisiblePostsは可視の投稿のみを返します。

ストア:

@computed get visiblePosts() { 
    return this._visiblePosts.map(uuid => this._posts.get(uuid)); 
} 

次に、あなたのコンポーネントで、あなただけ見えポストレンダリングすることができます:

コンポーネント:

this.props.store.visiblePosts.map(post => { 
return <PostsTreeGroup ...> 
}) 

を私はまた、あなたが並べ替えのいくつかの並べ替えを行う参照してください?

次に、店舗にソート方法(たとえば、プロパティを設定する)を教え、次に店舗にvisiblePostsメソッドで並べ替えをさせます。

2

少量の添加:(ActivePostsStore)あなたはそのインスタンスではなく、プロバイダにクラスを通過していることを一見思えます。実際の店舗を利用できるようにクラスをインスタンス化するようにしてください。 (インスタンスを作成した場合は、小文字の最初の文字を使用することをお勧めします)

関連する問題