2017-06-17 70 views
0

我有一個家庭組件,searchbarReactJs如何在初始渲染後重新調用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.valuesubmitted: 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" 
 
    } 
 
}

+0

內進行,以fetchRecipes呼叫(食物)?你使用什麼版本的反應路由器?提交package.json –

+0

已添加package.json。我有重定向,因爲我想將主頁作爲簡潔的介紹用戶界面,在我提交食品查詢後重定向到搜索/結果。在內部搜索/結果中,我想仍然可以執行api調用。有點像Google.com。 https://github.com/hyrosian/nutrion是github鏈接。 – Hyrule

回答

1

,爲什麼你有一個UI組件內部重定向你也許能夠給handleSubmit

handleSubmit(e) { 
    e.preventDefault(); 
    let recipes = await = fetchRecipes(food); 
    let food = e.target.value; 
    this.setState({ 
     food, recipes 
    }); 
} 
+0

哦當然!失去了複雜性,對我來說都是新的。謝謝! – Hyrule

相關問題