这是一个复杂的问题。希望我能解释一下,以便每个人都能理解该错误
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吗?