2017-01-27 56 views
0

让我们asume,我有三个组成部分:正确的方式来调用外部组件的方法React.js

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

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

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

RecentArticleList是一个从服务器获取最近10篇文章并显示它的组件。像ArticleFinder一样,用户单击列表项将显示< ArticleViewer/>,并且如果< ArticleViewer/>已安装,< ArticleViewer/>只需重新加载文章。

ArticleFinder和RecentArticleList组件接收简短的文章中的数据是这样的:

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

而且ArticleViewer会收到类似这样的更具体的数据:

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

这仅仅是为了降低传输的大小,服务器将尽可能地响应最小数据。因此,对于来自ArticleViewer的显示内容和文件以及其他文件,此组件必须调用一些getData方法。

请注意,这3个组件可以同时存在,它们在屏幕上有自己的范围。它们可以被重叠,但它们仍然在同一时间,同一屏幕上。

所以当ArticleViewer挂载时,它会调用自己的getData方法并显示结果,但问题是如果ArticleViewer已经挂载,请单击RecentArticleList中的列表或ArticleFinder不会触发ArticleViewer的getData,因为组件未卸载并且安装。

我对此使用了React Router 4.x,因此我可以重定向url,但仍然没有办法在ArticleFinder和RecentArticleList中强制调用ArticleViewer.getData。

有些地方,我用某种方法做了。我只是检查,从阵营路由器(this.props.params)发生了变化,然后调用GetData方法类似这样的接收道具:

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

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

有没有办法更优雅地解决这个问题?特别是,有些类似React(如果存在)?

代码是相当混乱,添加更多的功能使更丑陋,我想解决这个问题。我知道在编程中没有答案,但是我认为可以存在可读的解决方案。

任何建议将非常感激。谢谢!

回答

4

这些组件似乎在它们之间共享状态和功能。您可以将此状态移至包含这三个组件的组件,只需将文章传送至<ArticleViewer>即可。

+0

嗯..有趣。我从来没有这样想过。我会尝试。谢谢! – modernator

2

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

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

确保id对每篇文章都是唯一的。

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

+0

你的解决方案看起来不错,但在我的情况下,这会造成另一个问题:动画。我没有提到动画,但ArticleViewer已经卸载/装载动画(如滑动和向下),创建新实例将生成2个不同的ArticleViewer,并且它们将同时执行动画。我认为这可能是奇怪的,所以它不适合我的情况。但我会试试这个,谢谢! – modernator

+0

这是工作,但正如我所料,它有一个动画问题。如果不需要动画,这可以很方便。谢谢! – modernator

1

的阵营路由器V4的方法是使用自定义渲染功能的文章查看路线 -

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

,这会使得在航线变化的新ArticleViewer组件。

+0

看起来很甜!我会尝试一下,谢谢! – modernator

+0

我试过这个,但不会工作。我刚刚为此做了回购,所以请查看:https://github.com/rico345100/react-router-url-changes-xhr-test – modernator

+0

我的错误是,您需要在ArticleView上使用“键”来呈现它每次都重新播放(@ Thunderbird是对的),但是像你说的那样把动画搞砸了。其他选择是将状态作为@skAstro建议(首选)移动,或将getData移动到外部组件中,该组件将获取文章,然后将其呈现给ArticleViewer组件。 – hazardous