我正在尝试调用一个api并获取数据;由我的表单定义,并将onclick附加到我的api。我只是做了很短的时间,所以任何帮助将不胜感激。我的主要问题(我认为)是如何正确添加到api调用,如何从表单到api请求获取我的表单以及如何获取该表单以补充我的状态。我看过其他一些与此类似的帖子,但它们让我更加困惑,因为它们使用了不同的调用和api方法或其他一些问题,这些问题比开始时还给我带来了更多问题。任何帮助,将不胜感激。
import React, { Component } from 'react';
import { Navbar, Form, FormControl, Button } from 'react-bootstrap';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { faCocktail } from '@fortawesome/free-solid-svg-icons';
import { INGREDIENT_SEARCH_API_URL } from '../../config';
class Nav extends Component{
constructor(props) {
super(props);
this.state = {
drinks: [], //is this the right field from the api?
};
}
componentDidMount() {
const requestOptions = {
method: 'GET',
}
fetch(INGREDIENT_SEARCH_API_URL + this.state, requestOptions)
// what gets appended to the api?
.then(res => {
if (!res.ok) {
console.log('Blame it on the rain');
}
return res.json();
})
.then(responseData => {
this.setState({ drinks: responseData });
})
}
render() {
return (
<div className="Nav">
<Navbar bg="light" expand="lg">
<Navbar.Brand href="#home">
<FontAwesomeIcon icon={faCocktail} /> Mix It Up!
</Navbar.Brand>
<Navbar.Toggle aria-controls="basic-navbar-nav" />
<Navbar.Collapse id="basic-navbar-nav">
<Form inline>
<FormControl type="text" placeholder="Search" className="mr-sm-2" />
<Button type="submit" onClick={() => this.getdrinks()} variant="outline-success">Search</Button>
{/* What goes into the onClick function? */}
</Form>
</Navbar.Collapse>
</Navbar>
<div className="NavContent">
{this.state.drinks.map(drink => ( drink ))}
</div>
</div>
)
}
}
export default Nav
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
答案 0 :(得分:0)
您需要.catch()
来处理Promise拒绝。本质上,当API请求失败时,执行的只是后备逻辑。
此外,您的API请求看起来不正确。您不必将state
对象放在路径中。我假设您真正想要的是从Drinks数组中添加一个字符串。
componentDidMount() {
const requestOptions = {
method: 'GET',
}
fetch(INGREDIENT_SEARCH_API_URL + "/" + this.state.drinks[0], requestOptions)
// what gets appended to the api?
.then(res => {
if (!res.ok) {
console.log('Blame it on the rain');
}
return res.json();
})
.then(responseData => {
this.setState({ drinks: responseData });
})
.catch((errors) => {
console.log(errors)
})
}
答案 1 :(得分:0)
您为什么要在Api端点网址后附加this.state。 fetch的第一个参数是端点url,它必须是一个字符串。 fetch(url,{options})。 如果您想通过url传递查询,请使用'?'
const data=["aa","bb","cc"]
const stringData=data.join()
const params='?'+stringdata
fetch(INGREDIENT_SEARCH_API_URL+params, requestOptions)
.then(responseData => {
this.setState({ drinks: responseData });
})
.catch(res => {
if (!res.ok) {
console.log('Blame it on the rain');
}
})
答案 2 :(得分:0)
所以,我终于想通了。谢谢您的帮助。
export default class App extends Component {
constructor(props) {
super(props);
this.textInput = React.createRef();
this.searchValue = '';
this.state = {
drinks: []
}
}
handleChange = () => {
console.log('change', this.searchValue);
this.searchValue = this.textInput.current.value;
}
handleSearchClick = () => {
const requestOptions = {
method: "GET"
};
fetch(INGREDIENT_SEARCH_API_URL + this.searchValue, requestOptions)
.then(res => {
if (!res.ok) {
console.log('error');
}
return res.json();
})
.then(response => {
console.log(response.drinks);
this.setState({ drinks: response.drinks });
this.props.history.push('/');
})
.catch(err => {
console.log(err);
this.props.history.push('/');
})
}
gotoDrink = (id) => {
this.props.history.push('/d/' + id)
}
render() {
return (
<div className="App">
<Navbar bg="light" expand="lg">
<Navbar.Brand href="#home"><FontAwesomeIcon icon={faCocktail} /> Mix It Up!</Navbar.Brand>
<Navbar.Toggle aria-controls="basic-navbar-nav" />
<Navbar.Collapse id="basic-navbar-nav">
<Form inline>
<FormControl type="text" placeholder="Search" className="mr-sm-2" ref={this.textInput} onChange={() => this.handleChange()} />
<Button variant="outline-success" onClick={() => this.handleSearchClick()}>Search</Button>
</Form>
</Navbar.Collapse>
</Navbar>
<div className="Content">
<Route
path="/" exact
render={() => (
<div className="LeftContent">
{this.state.drinks.map(drink => (
<div className="DrinkName" onClick={() => this.gotoDrink(drink.idDrink)}>
{drink.strDrink}
</div>
))}
</div>
)}
/>
<Route
path="/d/:id"
render={(props) => <DrinkComponent {...props} />}
/>
</div>
</div>
)
}
}