Mobx状态树,Mobx反应和RenderProps的组合未更新react组件

时间:2019-04-10 15:33:25

标签: reactjs mobx mobx-react mobx-state-tree

这是一个复杂的问题。希望我能解释一下,以便每个人都能理解该错误

1)父级组件。

@observer
export class Edit extends React.Component<IProps> {
  article: any

  componentWillMount() {
    const articleId = this.props.routerStore!.routerState.params.id!

    this.article = ArticleModel.create({ id: articleId || null })
    this.article.init()
  }

  render() {
    if (!this.article) {
      return <div>loading...</div>
    }

    return <div className='main-wrapper'>
      <EditArticle article={this.article} />
    </div>
  }
}

2)子组件 它使用react-beautiful-dnd允许拖放文章布局。该库使用RenderProps (provided: any, snapshot)


@observer
export class EditArticle extends React.Component<IProps> {
  render() {
    return <div className='main-column article-target'>
      <Droppable
        ignoreContainerClipping
        direction={'vertical'}
        droppableId='article'
        key={'article'}
      >
        {(provided: any, snapshot: any) => {
          return <ObservedDragDropContext
              provided={provided}
              snapshot={snapshot}
            >
              {this.props.article.layout.map((el: any, index: number) => {
                return <WithDragable
                  key={getPath(el)}
                  id={getPath(el)}
                  index={index}
                  remove={() => {}}
                >
                  <div className='layout-item'>
                    <Layout key={getPath(el)} item={el} />
                  </div>
                </WithDragable>
              })}
            </ObservedDragDropContext>
        }}
      </Droppable>
    </div>
  }
}

Article是一个mobx状态树模型。 这是模型的actions属性的init方法:

init() {
  const run = flow(function*() {
    const res = yield getArticle(self.id)
    applySnapshot(self, res)
  })

  run()
},

流程如下: 1)创建文章 2)初始化文章 3)我希望在收到回复并在该文章上应用applySnapshot后看到该文章更新

但是运行applySnapshot之后,子组件不会重新呈现。我检查并运行applySnapshot,并且该文章具有从后端接收的更新值。

我认为问题是因为我在子组件中使用了RenderProps,这在某种程度上造成了干扰并限制了组件的重新渲染。

棘手的一点是,如果我添加

{this.props.article.layout.map((el: any, index: number) =>
  <Layout key={getPath(el)} item={el} />
)}
render函数中子组件中的

可以解决此问题,并且初始组件得到更新。因此,仅通过重新渲染道具,子组件便会重新渲染自身,并通过重新渲染Drappable和RenderProps隐式修复我的初始错误。

可能的解决方案1:,如果我使用其他未使用RenderProps的react DND库,则应进行所有更新。但是我不想这样做,因为react-beautiful-dnd的动画效果不错,我需要重构一些代码。

我无法理解为什么不重新显示Child组件。

因为我仅在renderProps内部使用this.props.article,所以子组件是否不知道它依赖于文章?

我可以避免使用renderProps吗?

0 个答案:

没有答案