在React中对API fetch-onClick进行更改



我正在原型设计一个UI,并从React:中这样的API获取数据

componentWillUpdate() {
fetch(this.state.api + this.state.query  +".json" + this.state.key)
.then(response => {
if (response.ok) {
return response.json();
} else {
throw new Error('Oops')
}
})
.then(data => this.setState({ results: data.results, isLoading: false}))
.catch(error => this.setState({ error, isLoading: false }))
}

这里有一个我想让用户访问的其他可能类别的列表

<li data-facet="arts" onClick={this.handleCategory}>Arts</li>

和一个类似的处理方法:

handleCategory(event) {
this.setState({
query: event.target.getAttribute('data-facet')
})
}

如何让UI更新并显示新类别中的数据?这几天来我一直在想这个。我已经编写了几种成功更新获取字符串的方法,但都没有强制组件重新渲染和显示新项。谢谢


使用完整的组件代码进行更新:

import React, { Component } from 'react'
import Moment from 'moment'
import MaterialIcon from 'material-icons-react'
import '../assets/styles/app.scss'
class App extends Component {
constructor(props) {
super(props);
this.state = {
error: null,
isLoading: false,
isMenuOpen: false,
results: [],
api: "the//api//here",
query: "",
key: "?api-key=XXXXXX"
};
this.handleMenu = this.handleMenu.bind(this)
this.handleCategory = this.handleCategory.bind(this)
}
handleMenu() {
this.setState({
isMenuOpen: !state.isMenuOpen
})
}
handleCategory(event) {
this.setState({
query: event.target.getAttribute('data-facet')
})
}
componentDidMount() {
fetch(this.state.api + this.state.query  +".json" + this.state.key)
.then(response => {
if (response.ok) {
return response.json();
} else {
throw new Error('Oops')
}
})
.then(data => this.setState({ results: data.results, isLoading: false}))
.catch(error => this.setState({ error, isLoading: false }))
}
render() {
const { results, isLoading, error } = this.state
if (error) {
return <div className="cards">{error.message}</div>
}
if (isLoading) {
return <div className="cards">Loading...</div>;
}
return (
<div className="wrapper">
<div className="menu-trigger"><MaterialIcon icon="menu"/></div>
<div className="menu">
<ul>
<li data-facet="arts" onClick={this.handleCategory}>Arts</li>
<li data-facet="automobiles" onClick={this.handleCategory}>Automobiles</li>
<li data-facet="books" onClick={this.handleCategory}>Books</li>
<li data-facet="business" onClick={this.handleCategory}>Business</li>
<li data-facet="fashion" onClick={this.handleCategory}>Fashion</li>
<li data-facet="food" onClick={this.handleCategory}>Food</li>
<li data-facet="health" onClick={this.handleCategory}>Health</li>
<li data-facet="home" onClick={this.handleCategory}>Home</li>
</ul>
</div>
<div className="cards">
{results.slice(0, 10).map(result => (
<div className="cards__card" key={result.title}>
<a href={result.url} target="_blank"><h5>{result.title}</h5></a>
<p>{result.abstract}</p>
<p className="small">Published {Moment(result.published_date).format('MMMM Do YYYY, h:mm a')}</p>
</div>
))}
</div>
</div>
);
}
}
export default App

为了让组件使用更新的数据重新渲染,您需要更新状态变量。

假设您将数据存储在this.state.results-但是,您没有在handleCategory中更新此状态。

你可以做一些事情:

  • 抽象您的fetch调用,使其可重用
  • 使用箭头函数来摆脱构造函数中的绑定
  • 去掉componentWillUpdate生命周期,因为它是多余的
class App extends Component {
constructor(props) {
super(props);
this.state = {
isLoading: false,
results: [],
error: null,
};
}
fetchData = (url, query, key) => {
fetch(`the/api/${url}${query}.json?api-key${key}`)
.then(res => res.ok && res.json())
.then(data => this.setState({ results: data.results, isLoading: false }))
.catch(error => this.setState({ error, isLoading: false }));
}
componentDidMount() {
fetchData('api_url', 'all', 'key_here');
}
handleCategory = (e) => {
const cat = e.target.getAttribute('data-facet');
fetchData('api_url', cat, 'key_here');
}
render() {
const { isLoading, results, error } = this.state;
if (isLoading) {
return <div className="loading-icon"></div>
}
if (error) {
return <div className="error"></div>    
}
return (
<div className="wrapper">
<button data-facet="arts" onClick={this.handleCategory}>Arts</button>
{results.map(res => ...)}
</div>
);
}
}

最新更新