2017-06-17 115 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