繁体   English   中英

在React.js中调用外部组件方法的正确方法

[英]Proper way to invoke external component's method in React.js

假设我有三个组成部分:

  • <ArticleFinder />
  • <ArticleViewer />
  • <RecentArticleList />

ArticleFinder是一个从服务器获取文章列表并显示它的组件。 如果用户单击列表项,将显示<ArticleViewer />。

ArticleViewer是一个从服务器获取单个文章并显示它的组件。

LatestArticleList是一个组件,可从服务器获取最近的10篇文章并进行显示。 与ArticleFinder一样,在用户单击时,列表项将显示<ArticleViewer />,如果<ArticleViewer />已安装,则<ArticleViewer />只需重新加载文章即可。

ArticleFinder和LatestArticleList组件正在接收简短的文章数据,如下所示:

[{ _id: 1, title: 'Helloworld', date: '...' }, { _id: 2, title: 'Farewell!', date: '...' }]

而且ArticleViewer将收到更具体的数据,例如:

{ _id: 1, title: 'Helloworld', date: '...', content: '<p>Helloworld!</p>', files: [ ... ], tags: [ ... ] }

这只是为了减少传输的大小,服务器将响应尽可能少的数据。 因此,对于显示ArticleViewer的内容和文件以及其他内容,此组件必须调用了某种getData方法。

请注意,这三个组件可以同时存在,它们在屏幕上具有自己的范围。 它们可以被包裹,但是它们仍在同一时间,同一屏幕中。

因此,在装入ArticleViewer时,它将调用自己的getData方法并显示结果,但是问题是,如果已经装入ArticleViewer,则单击从LatestArticleList或ArticleFinder中的列表将不会触发ArticleViewer的getData,因为没有卸载和装入组件。

我为此使用了React Router 4.x,因此我可以重定向url,但是仍然无法在ArticleFinder和LatestArticleList中强制调用ArticleViewer.getData。

不知何故,我用某种技巧来做到这一点。 我只是检查了从React Router(this.props.params)接收到的props是否已更改,然后像这样调用getData方法:

componentWillReceiveProps(nextProps, nextState) {
    if(nextProps.location.pathname !== prevPath) {
        prevPath = nextProps.location.pathname;
        this.getArticles(category, search);
    }
}

即使刷新页面,它实际上仍在工作,但我不喜欢它,至少对我来说,它不直观,不优雅。

有没有办法更优雅地解决这个问题? 尤其是某种类似的React(如果存在)?

代码是一团糟,添加更多功能会更加难看,我想解决这个问题。 我知道编程中没有答案 ,但是我认为可以存在可读的解决方案。

任何建议将不胜感激。 谢谢!

这些组件似乎在它们之间共享状态和功能。 您可以将此状态移动到包含这三个组件的组件,然后将文章传递到您的<ArticleViewer>

您可以使用key prop创建一个全新的组件实例,这与您第一次使用该组件完全相同。

<ArticleViewer {...yuorProps} key={id_of_article}/>

确保每个文章的ID都是唯一的。

请记住,您将不会使用现有组件,而最终会创建新组件。

React Router v4的方式是对商品视图路由使用自定义渲染功能-

<Match pattern="/:articleid" 
    render={({params}) => <ArticleViewer article={params.articleid} />}/>

这将在路线更改时呈现一个新的ArticleViewer组件。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM