我有一个家庭组件,searchbar
。ReactJs如何在初始渲染后重新调用API?
const Intro = (props) => {
return (
<Searchbar
onSubmit={props.onSubmit}
onChange={props.onChange}
value={props.value}
header='Nutrion'>
</Searchbar>
)
}
Searchbar是一个受控组件。它得到的传递事件处理
handleSubmit(e) {
e.preventDefault()
this.setState({
food: this.state.value,
submitted: true
})
}
如果里面搜索栏值获得的提交,它设置状态food: this.state.value
和submitted: true
。
submitted && <Redirect to={{
pathname: `/search/results`,
search: `?food=${food}`,
}} />
Submitted true
触发重定向到结果组件,以及一个查询字符串,在搜索栏提交的食品合格。
componentDidMount() {
console.log('hiii')
const food = this.state.food || queryString.parse(this.props.location.search).food
fetchRecipes(food).then(recipes => {
if (recipes === null) {
return this.setState (
{
error: 'Server failed to respond. Please try again.',
loading: false
})
}
this.setState({
error: null,
recipes: recipes,
loading: false,
isFetched: true
})
})
}
这是问题所在。这是ComponentDidMount()
里面的重定向到class Results
。它使用我们先前传递的查询字符串并对其进行解析。这个结果用于API请求,返回的数据被传递给this.state.recipes
。一切正常。数据被传递到recipeList
{!this.state.loading && <Recipelist recipes={this.state.recipes} />}
但是,这只适用于INITIAL渲染。如果我通过提交结果中的另一个Searchbar中的值来更改this.state.food,它不会重新请求API数据并使用新食谱更新RecipeList。你怎样才能让一个新的API请求每个项目提交一个新值到this.state.food
并重新呈现RecipeList?
我已张贴下面链接到相关文件:
import React from 'react'
import { Redirect } from 'react-router-dom'
import Searchbar from './../ui/Searchbar'
import {
Jumbotron,
// PageHeader
} from 'react-bootstrap'
const Intro = (props) => {
return (
<Searchbar
onSubmit={props.onSubmit}
onChange={props.onChange}
value={props.value}
header='Nutrion'>
</Searchbar>
)
}
class Home extends React.Component {
constructor(props) {
super(props)
this.state = {
submitted: false,
food: '',
value: ''
}
this.handleSubmit = this.handleSubmit.bind(this)
this.handleChange = this.handleChange.bind(this)
}
handleChange(e) {
this.setState({ value: e.target.value })
}
handleSubmit(e) {
e.preventDefault()
this.setState({
food: this.state.value,
submitted: true
})
}
render() {
// REMINDER: toegang tot path is via this.props.match => match.url object
const submitted = this.state.submitted
const food = this.state.food
return (
<Jumbotron>
{
!submitted &&
<Intro onSubmit={this.handleSubmit}
onChange={this.handleChange}
value={this.state.value}/>
}
{
submitted &&
<Redirect to={{
pathname: `/search/results`,
search: `?food=${food}`,
}} />
}
</Jumbotron>
)
}
}
export default Home
import React, {Component} from 'react'
import {Jumbotron} from 'react-bootstrap'
import Searchbar from './../../ui/Searchbar'
import { fetchRecipes } from './../../utils/api'
import queryString from 'query-string'
import Recipelist from './Recipelist'
class Results extends Component {
constructor(props) {
super(props)
this.state = {
value: '',
food: '',
recipes: null,
isFetched: false,
error: null,
loading: true
}
this.handleChange = this.handleChange.bind(this)
this.handleSubmit = this.handleSubmit.bind(this)
}
handleChange(e) {
this.setState({ value: e.target.value })
}
componentDidMount() {
console.log('hiii')
const food = this.state.food || queryString.parse(this.props.location.search).food
fetchRecipes(food).then(recipes => {
if (recipes === null) {
return this.setState (
{
error: 'Server failed to respond. Please try again.',
loading: false
})
}
this.setState({
error: null,
recipes: recipes,
loading: false,
isFetched: true
})
})
}
handleSubmit(e) {
e.preventDefault()
this.setState({
food: this.state.value
})
}
render(){
if (this.state.loading) {
return <p> Loading ... </p>
}
if (this.state.error) {
return (
<div>
<p>{this.state.error}</p>
{/*<Link to='/'>try again</Link>*/}
</div>
)
}
return (
<div>
<Jumbotron>
<Searchbar
value={this.state.value}
onSubmit={this.handleSubmit}
onChange={this.handleChange}/>
</Jumbotron>
{!this.state.loading && <Recipelist recipes={this.state.recipes} />}
</div>
)
}
}
export default Results
{
"name": "nutrion",
"version": "0.1.0",
"private": true,
"dependencies": {
"normalize-css": "^2.3.1",
"prop-types": "^15.5.10",
"query-string": "^4.3.4",
"react": "^15.5.4",
"react-bootstrap": "^0.31.0",
"react-dom": "^15.5.4",
"react-router-dom": "^4.1.1",
"semantic-ui-react": "^0.68.5"
},
"devDependencies": {
"react-scripts": "1.0.7"
},
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test --env=jsdom",
"eject": "react-scripts eject"
}
}
内进行,以fetchRecipes呼叫(食物)?你使用什么版本的反应路由器?提交package.json –
已添加package.json。我有重定向,因为我想将主页作为简洁的介绍用户界面,在我提交食品查询后重定向到搜索/结果。在内部搜索/结果中,我想仍然可以执行api调用。有点像Google.com。 https://github.com/hyrosian/nutrion是github链接。 – Hyrule