Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/reactjs/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Reactjs 如何在url参数更改时重新加载组件?_Reactjs_React Router - Fatal编程技术网

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
,带。。。?