我有一個家庭組件,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