假设我有一个嵌套的 URI 结构,如下所示:
http://example.com/collections/{id}
http://example.com/collections/{collectionId}/categories/{id}
http://example.com/collections/{collectionId}/categories/{categoryId}/book/{id}
我可以使用 react-router
在页面加载和 URI 更改时呈现正确的组件。
让我们来看第一种情况:
假设我们有一个 CollectionShow
组件。
当组件首次加载时,我可以从 URI 中提取集合 ID 并加载正确的集合:
componentDidMount () {
this.loadCollection(this.props.match.params.id);
}
(假设 loadCollection
使用 AJAX 调用加载集合并将其设置为组件的状态。)
但是,当 URI 更改时(例如,通过用户单击 <Link>
,react-router
不会完全重新构建组件,它只是更新其属性,迫使其重新呈现。因此,在为了更新组件的状态,我们还需要在更新时更新状态:
componentDidUpdate(prevProps) {
if (!this.state.collection || this.collectionDidChange(prevProps)) {
this.loadCollection(this.props.match.params.id);
}
}
collectionDidChange(prevProps) {
return String(prevProps.match.params.id) !== String(this.props.match.params.id)
}
到目前为止一切顺利。但是第二个 URL 呢?
http://example.com/collections/{collectionId}/categories/{id}
假设我们有一个 CategoryShow
组件。
现在我们不仅要考虑 collectionId
不断变化的,也是类别 ID。如果 ID 发生变化,我们必须重新加载集合,如果 发生变化,我们也必须重新加载类别。
问题与三级嵌套(BookShow
组件)复合。我们最终得到这样的结果:
componentDidUpdate(prevProps) {
if (!this.state.collection || this.collectionDidChange(prevProps)) {
this.loadCollection(this.props.match.params.collectionId);
}
if (!this.state.category || this.collectionDidChange(prevProps) || this.categoryDidChange(prevProps)) {
this.loadCollection(this.props.match.params.collectionId)
.then(() => this.loadCategory(this.props.match.params.categoryId);
}
if (!this.state.book || this.collectionDidChange(prevProps) || this.categoryDidChange(prevProps) || this.bookDidChange(prevProps)) {
this.loadCollection(this.props.match.params.collectionId)
.then(() => this.loadCategory(this.props.match.params.categoryId)
.then(() => this.loadBook(this.props.match.params.id);
}
}
这不仅笨拙,还会导致三个组件之间的大量代码重复,CollectionShow
, CategoryShow
和 BookShow
.
使用 redux 不会有太大帮助,因为当 URI 更改时我们仍然必须更新全局状态。
是否有一种干净、高效、React 友好的方式来处理此类嵌套资源的更新?
最佳答案
您可以创建一个 CollectionPage
处理所有 AJAX 调用并保持数据状态的组件。
这可以传递 collection
, category
/categories
和 books
到组件( CollectionShow
、 CategoryShow
和 BookShow
)。
在CollectionPage
你可以使用 componentDidUpdate
和 componentDidMount
正如你介绍的那样。
你的 <*>Show
组件将对 props.match.params.*
一无所知并且只会获取呈现所需内容所需的数据。
CollectionPage
可以用于您的所有路线,或者您可以将路线更改为类似
/collections/:collectionId?/:categoryId?/:bookId?
制作所有参数选项。您可以在 CollectionPage
中检查可用的 ID .
希望对您有所帮助!
关于javascript - react : loading and updating nested resources when URI changes without excess duplication?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52334124/