繁体   English   中英

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

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

我有一个带有搜索searchbar的Home组件。

const Intro = (props) => {

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

搜索栏是一个受控组件。 它通过了事件处理程序

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

如果Searchbar中的值得到了提交,它将设置状态food: this.state.valuefood: this.state.value submitted: true

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

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

    }

这是问题所在。 这是重定向到class Results内的ComponentDidMount() 它采用我们之前传递的查询字符串并进行解析。 其结果用于API请求,并将返回的数据传递到this.state.recipes 一切正常。 数据传递到recipeList

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

但这仅适用于INITIAL渲染。 如果我通过在“结果”内部(另一个)“搜索栏”内提交值来更改this.state.food,则它不会重新请求API数据,也不会使用新配方更新RecipeList。 如何将每个项目的新值都提交给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" } } 

您可能可以在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