简体   繁体   English

ReactJs初始渲染后如何调用API?

[英]ReactJs How to re-call API after initial render?

I have a Home component with a searchbar . 我有一个带有搜索searchbar的Home组件。

const Intro = (props) => {

    return (
        <Searchbar 
        onSubmit={props.onSubmit}
        onChange={props.onChange} 
        value={props.value}
        header='Nutrion'>
        </Searchbar>
    )
}

Searchbar is a controlled component. 搜索栏是一个受控组件。 It get's passed event handlers 它通过了事件处理程序

handleSubmit(e) {
        e.preventDefault()
        this.setState({
            food: this.state.value,
            submitted: true
        })
    }

If the value inside Searchbar get's submitted, it sets state food: this.state.value and submitted: true . 如果Searchbar中的值得到了提交,它将设置状态food: this.state.valuefood: this.state.value submitted: true

submitted && <Redirect to={{
           pathname: `/search/results`,
           search: `?food=${food}`,
                        }} />

Submitted true triggers a redirect to Results component, passing along a query string with the submitted food in the searchbar. Submitted true触发重定向到Results组件,并在查询栏中传递查询字符串和已提交的食物。

   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
            })
        })

    }

Here is the problem. 这是问题所在。 This is the ComponentDidMount() inside the redirected to class Results . 这是重定向到class Results内的ComponentDidMount() It takes the query string we passed earlier and parses it. 它采用我们之前传递的查询字符串并进行解析。 The result of this is used for an API request and the returning data is passed to this.state.recipes . 其结果用于API请求,并将返回的数据传递到this.state.recipes Everything works. 一切正常。 Data gets passed to the recipeList 数据传递到recipeList

{!this.state.loading && <Recipelist recipes={this.state.recipes} />}

But this only works on INITIAL render. 但这仅适用于INITIAL渲染。 If i change this.state.food by submitting the value inside (another) Searchbar inside Results, it doesn't re-request API data and update RecipeList with new Recipes. 如果我通过在“结果”内部(另一个)“搜索栏”内提交值来更改this.state.food,则它不会重新请求API数据,也不会使用新配方更新RecipeList。 How can you make a new API request each item a new value is submitted to this.state.food and re-render RecipeList? 如何将每个项目的新值都提交给this.state.food并重新呈现RecipeList?

I have posted links to relevant files below: 我在下面发布了相关文件的链接:

 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" } } 

You might be able to place a call to fetchRecipes(food) within the handleSubmit 您可能可以在handleSubmit内调用fetchRecipes(food)

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM