首先,我没有经验的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
我的第一个问题是,我可以通过我的布局组件或_document.js中的Provider传递商店(我使用Next.js)。
/*Doesn't work. In root layout*/
<Provider store={ActivePostsStore}>
<Content />
</Provider>
每当我尝试使用Provider
时,我的商店都未定义。在RootLayout或_document.js中也是如此。当然,我为使用商店的组件提供了@observer
注释。但商店仍未定义。
然后,我尝试使用@inject('activePostsStore')
结果是错误,这告诉我,就像我根本没有提供任何商店。但是,实际上,我做到了。
SO!我决定直接注射它:
@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>
)
}
请有人帮助我让事情有效!
答案 0 :(得分:4)
<强>问题1:强>
提供程序仅在您在组件上调用注入时才有效,您希望商店出现在其道具中。所以你必须调用inject,否则商店是未定义的(因为没有人为你的商店设置组件的属性)。
您传递给inject的字符串必须是您在Provider中提供的属性名称。
你有:
<Provider store={ActivePostsStore}> // store is the property name
所以你也必须打电话
@inject('store')
然后mobx会查找密钥存储区,在您的提供程序中找到它并将其分配给您的组件。
<强>问题2:强>
您可以计算商店中的可见帖子,而不是相反。 所以方法visiblePosts只返回可见的帖子。
商店:
@computed get visiblePosts() {
return this._visiblePosts.map(uuid => this._posts.get(uuid));
}
然后在您的组件中,您只能渲染可见的帖子:
组件:
this.props.store.visiblePosts.map(post => {
return <PostsTreeGroup ...>
})
我也看到你做某种排序?
然后,您可以告诉您的商店如何排序(例如设置属性),然后让您的商店在visiblePosts方法中进行排序。
答案 1 :(得分:3)
小补充:乍一看,您正在将类传递给提供程序,而不是实例(ActivePostsStore
)。确保实例化您的类,以便您可以使用实际的商店。 (如果你确实创建了一个实例,那么最好坚持使用小写的第一个字母)