tom*_*hes 5 javascript api components reactjs react-router
我正在尝试使用 React 和 React-router v4 来渲染一些元素。
这个想法是,该组件是来自网站的文章列表,每个路由使用不同的 API 密钥从不同的网站获取文章。
我使用单个组件来显示文章,并且对于每个路由,我想传递不同的 API 密钥。
我遇到的问题是每个路由都使用相同的 API 密钥,这是访问的第一个路由的密钥。
源代码如下:
var APIKeys = {
BBCKey: 'https://newsapi.org/v1/articles?source=bbc-sport&sortBy=top&apiKey=foo',
ESPNKey: 'https://newsapi.org/v1/articles?source=espn&sortBy=top&apiKey=foo',
FourFourTwoKey: 'https://newsapi.org/v1/articles?source=four-four-two&sortBy=top&apiKey=foo'
}
let App = () => (
<BrowserRouter>
<div className="container">
<header>
<span className="icn-logo"><i className="material-icons">code</i></span>
<ul className="main-nav">
<li><NavLink exact to="/">Home</NavLink></li>
<li><NavLink to="/BBCSport">BBC Sport</NavLink></li>
<li><NavLink to="/FourFourTwo">FourFourTwo</NavLink></li>
<li><NavLink to="/ESPN">ESPN</NavLink></li>
</ul>
</header>
<Switch>
<Route exact path="/" component={Home} />
<Route path="/BBCSport" render={ () => <GetArticles APIKey={APIKeys.BBCKey} /> } />
<Route path="/FourFourTwo" render={ () => <GetArticles APIKey={APIKeys.FourFourTwoKey} /> } />
<Route path="/ESPN" render={ () => <GetArticles APIKey={APIKeys.ESPNKey} /> } />
<Route component={NotFound} />
</Switch>
</div>
</BrowserRouter>
);
export default App;Run Code Online (Sandbox Code Playgroud)
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>Run Code Online (Sandbox Code Playgroud)
import React, { Component } from 'react';
import axios from 'axios';
import ArticleList from './ArticleList';
export default class GetArticles extends Component {
constructor(props) {
super(props);
this.state = {
articleTitles: [],
loading: true
};
}
componentDidMount() {
axios.get(this.props.APIKey)
.then(response => {
let titles = response.data.articles.map( (currentObj) => {
return currentObj.title;
} );
this.setState({
articleTitles: titles,
loading: false
});
})
.catch(error => {
console.log('Error fetching and parsing data', error);
});
}
render() {
return (
<div>
<div className="main-content">
<h1 className="main-title">Articles</h1>
{ (this.state.loading) ? <p>Loading</p> : <ArticleList list={this.state.articleTitles} /> }
</div>
</div>
);
}
}Run Code Online (Sandbox Code Playgroud)
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>Run Code Online (Sandbox Code Playgroud)
我的两个问题是,使用这样的单个组件是一个好主意,即使它呈现不同的信息,还是我应该有一个组件来呈现每个不同的文章列表?
我该如何修复它以便使用适当的 API 密钥?
我认为原因是,componentDidMount只会在初始渲染之后被调用,因为您为每个路由使用相同的组件,所以componentDidMount不会再次被调用。您还需要使用componentwillreceiveprops生命周期方法,并检查是否收到新的 APIkey,然后在其中执行 api 调用。
组件安装后立即调用 componentDidMount()。需要 DOM 节点的初始化应该放在此处。如果您需要从远程端点加载数据,那么这是实例化网络请求的好地方。在此方法中设置状态将触发重新渲染。
在已安装的组件接收新的 props 之前调用 componentWillReceiveProps() 。如果您需要更新状态以响应 prop 更改(例如重置它),您可以比较 this.props 和 nextProps 并在此方法中使用 this.setState() 执行状态转换。
像这样编写组件:
export default class GetArticles extends Component {
constructor(props) {
super(props);
this.state = {
articleTitles: [],
loading: true
};
}
componentDidMount() {
console.log('initial rendering', this.props.APIKey)
this._callApi(this.props.APIKey);
}
componentWillReceiveProps(newProps){
if(newProps.APIKey != this.props.APIKey){
this._callApi(newProps.APIKey);
console.log('second time rendering', newProps.APIKey)
}
}
_callApi(APIKey){
axios.get(APIKey)
.then(response => {
let titles = response.data.articles.map( (currentObj) => {
return currentObj.title;
} );
this.setState({
articleTitles: titles,
loading: false
});
})
.catch(error => {
console.log('Error fetching and parsing data', error);
});
}
render() {
return (
<div>
<div className="main-content">
<h1 className="main-title">Articles</h1>
{ (this.state.loading) ? <p>Loading</p> : <ArticleList list={this.state.articleTitles} /> }
</div>
</div>
);
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1764 次 |
| 最近记录: |