Reactjs 如何在url参数更改时重新加载组件?
我有以下路线:-Reactjs 如何在url参数更改时重新加载组件?,reactjs,react-router,Reactjs,React Router,我有以下路线:- ReactDOM.render(( <Router history={browserHistory}> <Route path="/" component={app}> <IndexRoute component={home}/> <Route path="/articles" component={articles} /> <Route path="/a
ReactDOM.render((
<Router history={browserHistory}>
<Route path="/" component={app}>
<IndexRoute component={home}/>
<Route path="/articles" component={articles} />
<Route path="/articles/topics/:featureName" component={filteredArticles} />
</Route>
</Router>
), document.getElementById('app'));
ReactDOM.render((
),document.getElementById('app');
现在,当我请求/articles/topics/topic1时,使用API调用获取前5个内容。当用户再次到达页面底部时,将发出一个API调用,其中将获取接下来的5个内容。这很好(注意handlescroll函数检查页面底部,它没有什么小问题,所以现在已经被注释掉了。)
现在假设我从列表中选择下一个主题,所以url会发生变化,所以我的url会变为/articles/topics/topic2,现在我需要与上面提到的相同的东西,并为此主题调用API
以下是我当前的组件代码:-
import React from 'react';
import axios from 'axios';
import ArticleList from './ArticleList';
import Banner from './Banner';
import LeftNavBar from './LeftNavBar';
import RightNavbar from './RightNavbar';
import {url} from './Constants';
/*MERGE INTO ARTICLES ONCE SCROLL LOGIC IS FIXED*/
class FilteredArticles extends React.Component{
constructor(){
super();
{/* Adding global event listener,binding it to scroll event and adding it to handleScroll function */}
/*window.addEventListener("scroll", this._handleScroll.bind(this));*/
this.state ={
articles : [],
loadingFlag:false,
limit : 5,
offset :0,
subFeatureName:[],
flag: false
}
}
_getContent(){
let self=this;
axios.get(url+'/articles/filter/?filter=popular&category='+this.props.params.featureName+'&limit='+this.state.limit+'&offset='+this.state.offset)
.then(function(response){
/*Checking if limit has exceeded meta count, if it has stopped we dont call the APIS*/
if(self.state.limit >= response.data.meta.total_count){
self.setState({articles : self.state.articles.concat(response.data.results),
offset : self.state.limit,
limit: self.state.limit+self.state.offset,
subFeatureName: self.props.params.featureName,
loadingFlag: false}
)
}
else{
self.setState({articles : self.state.articles.concat(response.data.results),
offset : self.state.limit,
limit: self.state.limit+self.state.offset,
subFeatureName: self.props.params.featureName,
loadingFlag: true}
)
}
})
.catch(function(error){
console.log(error);
});
}
_handleScroll(){
/*Calling 5 more articles when someone scrolls down and reaches the page end
const windowHeight = window.innerHeight;
const scrollT = $(window).scrollTop();
if(windowHeight- scrollT < 200){
if(!this.state.loadingFlag){
this.setState({loadingFlag : true});
this._getContent();
}
}*/
}
componentDidMount(){
/*calling _getContent function to get first five articles on page load*/
console.log("got content");
this._getContent();
}
render(){
console.log("inside render");
return(
<div>
<Banner title="Article Page"/>
<div className="content-container">
<LeftNavBar/>
<div className ="feeds">
<div className="card">
{/* Sending hideSeeAll as prop to remove see all button on main article page*/}
<ArticleList articles={this.state.articles} hideSeeAll='true' keyword="Top Articles"/>
</div>
</div>
<RightNavbar/>
</div>
</div>
)
}
}
export default FilteredArticles;
从“React”导入React;
从“axios”导入axios;
从“/ArticleList”导入ArticleList;
从“./Banner”导入横幅;
从“/LeftNavBar”导入LeftNavBar;
从“/RightNavbar”导入RightNavbar;
从“./Constants”导入{url};
/*一旦固定了滚动逻辑,就可以合并到文章中*/
类FilteredArticles扩展React.Component{
构造函数(){
超级();
{/*添加全局事件侦听器,将其绑定到滚动事件并将其添加到handleScroll函数*/}
/*window.addEventListener(“滚动”,this._handleScroll.bind(this))*/
这个州={
第[…]条,
加载标志:false,
限额:5,
偏移量:0,
子功能名称:[],
旗帜:假
}
}
_getContent(){
让自我=这个;
axios.get(url+'/articles/filter/?filter=popular&category='+this.props.params.featureName+'&limit='+this.state.limit+'&offset='+this.state.offset)
.然后(功能(响应){
/*检查限制是否已超过元计数,如果已停止,则不调用API*/
if(self.state.limit>=response.data.meta.total\u计数){
self.setState({articles:self.state.articles.concat(response.data.results),
偏移量:self.state.limit,
限制:self.state.limit+self.state.offset,
子功能名称:self.props.params.featureName,
loadingFlag:false}
)
}
否则{
self.setState({articles:self.state.articles.concat(response.data.results),
偏移量:self.state.limit,
限制:self.state.limit+self.state.offset,
子功能名称:self.props.params.featureName,
loadingFlag:true}
)
}
})
.catch(函数(错误){
console.log(错误);
});
}
_handleScroll(){
/*当有人向下滚动到页面末尾时,再调用5篇文章
const windowHeight=window.innerHeight;
常量scrollT=$(window.scrollTop();
如果(窗口高度-滚动<200){
如果(!this.state.loadingFlag){
this.setState({loadingFlag:true});
这个;
}
}*/
}
componentDidMount(){
/*调用_getContent函数获取页面加载的前五篇文章*/
日志(“获取内容”);
这个;
}
render(){
控制台日志(“内部渲染”);
返回(
{/*将HideseAll作为道具发送以删除主页上的“全部查看”按钮*/}
)
}
}
导出默认过滤器目录;
因此,基本上我试图理解,如果我有一个像/articles/topics/:featureName这样的路由,并且我调用一个像/articles/topics/topic1或/articles/topics/topic2这样的页面,那么可以重新加载组件(我需要再次调用不同的API来获取内容)
也就是说,对于/articles/topics/topic1,调用的API是
/api/v0/articles/filter/?filter=popular&category=topic1&limit=5&offset=0
对于/articles/topics/topic2,调用的API是
/api/v0/articles/filter/?filter=popular&category=topic2&limit=5&offset=0
有没有办法做到这一点?您不应该以这种方式查询API/更新组件状态,但这完全是另一个问题。也许考虑使用一种方法。 无论如何,您可以使用组件WillReceiveProps(nextProps)生命周期方法来接收路由器nextProps参数并再次查询API:
componentWillReceiveProps(nextProps) {
this._getContent(nextProps.params.featureName);
}
_getContent(featureName) {
...query your API
}
此外,如果您正在使用Redux,请进行如下检查以避免出现无限循环:
componentWillReceiveProps(newProps) {
if (this.props.someValue === newProps.someValue) {
this.props.fetchSomething(newProps.params.somethingName);
}
}
我尝试了以下方法:-componentWillReceiveProps(nextProps){console.log(“此处”);console.log(“props”+nextProps.params.featureName”);this.setState({articles:[],loadingFlag:false,limit:5,offset:0,subFeatureName:[],flag:false});console.log(“接收后”+JSON.stringify(this.state));this._getContent(nextrops.params.featureName);}但是在调用SetStateState()后尝试打印时,状态没有得到更新。SetState()不会立即改变this.state,而是创建挂起的状态转换。调用此方法后访问this.state可能会返回现有值。那么我应该如何使用它?它使用旧数据来调用APIs。在componentWillReceiveProps中调用this.setState()似乎不会触发额外的渲染(或者在您的情况下,根据API承诺的解析)。您使用的是react路由器,所以我假设您的应用程序大小合适?在这种情况下,我建议您使用状态容器(如Redux)来解决您的应用程序架构问题:投票支持Redux,我计划在下一个版本中使用Redux。因此,目前我在一篇文章中有5个主题,我认为为每个类别创建单独的路由比花时间调试更好。应该是
this.props.someValue!==newProps.someValue
,带。。。?