【问题标题】:How to pass state from a stateful component to another stateful component如何将状态从有状态组件传递到另一个有状态组件
【发布时间】:2018-12-15 04:38:27
【问题描述】:

我正在制作一个应用程序,它会为用户生成晚餐建议。我成功获取数据并输出。但我对过滤器非常坚持。

我对这项任务的想法是创建一个过滤器,用户可以选择一种美食,然后获得晚餐建议。我正在使用 Zomato API 来获取 resutuanrt 数据。我需要通过

我不知道如何将 food_id 从我的 CusisineOption 组件传递给我的 FoodGuide 组件。我需要将我的 CusisineOption 组件(我也从 Zomato 获得 id)中的美食 ID 传递给我的 FoodGuide 组件。然后使用 food_id 获取 JSON 文件。

如果有人能提供帮助并给我一些建议,我将不胜感激。这是我的代码:

CusisineOption 组件:

import React, { Component } from 'react';
import axios from 'axios';
import Aux from '../../hoc/Aux/Aux';

class Cuisines extends Component {
  state = {
    error: false,
    optionList: [],
    value: null
  }
  componentDidMount() {
      const config = { headers: {'user-key': 'myAPIkey'} };s
      axios.get(`https://developers.zomato.com/api/v2.1/cuisines?city_id=2891` , config) 
          .then(res => {
              this.setState({optionList: res.data.cuisines})
              console.log(this.state.optionList)
          })
          .catch(error => {
              this.setState({error: true})
          })
  }

    gotOption = (event) => {
      this.setState({value: event.target.value})
      console.log(this.state.value)
  }

    render() {
      const CuisinesCopy = [...this.state.optionList]
      const cuisineItems = CuisinesCopy.map((item) => {
        return(
            <option key={item.cuisine.cuisine_id.toString()} value={ item.cuisine.cuisine_id }>{item.cuisine.cuisine_name}</option>
        )
      })



      return (
        <Aux>
          <p>Goddamnit! I am going to get the json data</p>

          <select value={this.state.value} onChange={this.gotOption}>
              <option value="1">--Please select a cusion--</option>
              <option value="2">--Please select a cusion 2--</option>
              { cuisineItems }
          </select>
        </Aux>

        )
    }
  }

  export default Cuisines;

FoodGuide 组件: 值是我想使用 food_id 更新的值

class FoodGuide extends Component {
    state = {
        names: [],
        suggestion: null,
        getList: false,
        loading: false,
        error: false,
        changed: false,
        value: "2",
        list: []
    }

componentDidMount() {
    const config = { headers: {'user-key': 'APIKEY'} };
    axios.get(`/search?entity_id=2891&entity_type=city&count=50&sort=rating$&cuisines=${this.props.value}` , config) 
        .then(res => {
            this.setState({names: res.data.restaurants})
            console.log(this.state.names)
        })
        .catch(error => {
            this.setState({error: true})
        })
}


getSuggestion = () => { 
    let rSuggestion;
    if(this.state.names) {
        let randomR = this.state.names[Math.floor(Math.random()*this.state.names.length)];
        rSuggestion = randomR.restaurant.name
        //console.log(randomR.restaurant.name)
        this.setState({suggestion: rSuggestion})
    } 
    return rSuggestion
}

getRestaurantList = () => {
    let rData = <p>This is a suggestion</p>
    if(this.state.getList) {
        rData = this.state.names.map((r, i) => {
            return(
                <li key={i}>
                    <span>Name: { r.restaurant.name }</span>
                </li>
            )
        }) 

    }
    return rData
}

getRestaurantsHandler = () => {
    let rList = <p>Loading...</p>
    if(this.state.names) {
        this.setState({getList: true})
    }
    return rList
}

render () {

    return (
        <Aux>
            <h2>Food Guide</h2>
            <Cuisines />
            <Suggestion suggested={ this.getSuggestion } suggestion={this.state.suggestion}/>
            <RestaurantList getList={ this.getRestaurantsHandler } rList={ this.getRestaurantList() }/>
        </Aux>
    )
}

}

导出默认的 FoodGuide;

【问题讨论】:

    标签: javascript json reactjs axios


    【解决方案1】:

    试试这样的(我确实删除了一些样板,但你可以知道去哪里):

    class CuisineOption extends PureComponent {
      clicked = () => {
        this.props.onCuisineClick(this.props.id); // Call with cuisine id
      };
    
      render() {
        const { id, cuisine_name } = this.props;
    
        return (
          <option key={option.id} onClick={this.clicked}> 
            {cuisine_name}
          </option>
        );
      }
    }
    
    class Cuisines extends Component {
      state = {
        options: [],
      };
    
      componentDidMount() {
        axios
          .get('/cuisines')
          .then((result) => this.setState({ options: result.data.cuisines }));
      }
    
      render() {
        const { options } = this.state;
    
        return (
          <div>
            {options.map((option) => (
              <CuisineOption
                key={option.id}
                {...option}
                onCuisineClick={this.props.onCuisineClick} // Pass callback to each cuisine option
              />
            ))}
          </div>
        );
      }
    }
    
    class FoodGuide extends Component {
      state = {
        cuisineId: 0, // initial cuisine id
        names: [],
      };
    
      componendDidMount() {
        this.search(); // Initial searching
      }
    
      componendDidUpdate(prevProps, prevState) {
        if (prevState.cuisineId !== this.state.cuisineId) {
          this.search(); // Trigger search with new cuisine id
        }
      }
    
      search() {
        axios
          .get(`/search?cuisine${this.state.cuisineId}`)
          .then((result) => this.setState({ names: result.data.names }));
      }
    
      cuisineChanged = (id) => this.setState({ cuisineId: id }); // Callback called with new cuisine id
    
      render() {
        return <Cuisines onCuisineClick={this.cuisineChanged} />; // Pass callback to Cuisines component
      }
    }
    

    【讨论】:

      【解决方案2】:

      尽可能多地,我强烈推荐像 redux 这样的状态管理库。请检查 redux、redux react 和 redux-thunk/redux-saga 以获得更好的方法。

      【讨论】:

        猜你喜欢
        • 2019-12-11
        • 2020-03-12
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-09-28
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多