简体   繁体   English

如何将状态从有状态组件传递到另一个有状态组件

[英]How to pass state from a stateful component to another stateful component

I am making an app that will generate a dinner suggestion to users. 我正在制作一个会向用户生成晚餐建议的应用。 I successfully fetch the data and output it. 我成功获取了数据并将其输出。 But I am very stuck with the filter. 但是我非常喜欢过滤器。

My idea of this assignment is to create a Filter that users can select a cuisine, and then get a dinner suggestion. 我的任务是创建一个过滤器,用户可以选择一种美食,然后获得晚餐建议。 I am using the Zomato API to get the resutuanrt data. 我正在使用Zomato API来获取结果数据。 I need to pass the 我需要通过

I have no idea how to pass the cuisine_id from my CusisineOption component to my FoodGuide component. 我不知道如何将Cuisine_id从我的CusisineOption组件传递到FoodGuide组件。 I need to pass the cuisine_id from my CusisineOption component (I get the id from Zomato as well) to my FoodGuide component. 我需要将CusisineOption组件中的Cuisine_id(也从Zomato获得ID)传递给FoodGuide组件。 And then use the cuisine_id to get the JSON file. 然后使用Cuisine_id获取JSON文件。

I will be very appreciated if anyone can help and give me some suggestions. 如果有人可以帮助我并给我一些建议,我将不胜感激。 This is my code: 这是我的代码:

CusisineOption component: 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 component: Value is the value I wanna update using cuisine_id FoodGuide组件:值是我想使用Cuisine_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>
    )
}

} }

export default FoodGuide; 导出默认的FoodGuide;

Try something like this (I did remove some boilerplate but you can have an idea where to go): 尝试这样的事情(我确实删除了一些样板,但是您可以知道要去哪里):

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

在可能的情况下,我强烈建议使用状态管理库,例如redux。请检查redux,redux react和redux-thunk / redux-saga,以寻求更好的方法。

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

相关问题 如何将属性从有状态组件传递到包装子组件的 HOC 中使用的事件处理程序? - How can I pass attributes from a stateful component to an event handler used in an HOC wrapping a child component? 如何从有状态组件的句柄提交中呈现方法 - How to render method from handle submit of a stateful component 如何将值从状态传递到另一个组件 - How to pass values from a state to another component 状态组件调用的功能组件更改类型的道具 - Props from Stateful component calling Functional component changes type 将图像从列表(无状态)组件传递到显示(有状态)组件--react - passing image from list(stateless) component to display(stateful) component --react 反应克隆组件(无状态或有状态)以传递其他道具 - React clone component (stateless or stateful) to pass additional props 您可以向有状态组件传递一个函数以在 componentDidMount() 内运行吗? - Can you pass a Stateful Component a function to run inside componentDidMount()? 使用react-router时,是否存在将道具从有状态组件传递到无状态组件的另一种方法 - When using react-router, is there a different way to pass props from a stateful component to a stateless one ReactJS:无状态组件中的有状态子级 - ReactJS: Stateful children in stateless component 具有状态反应组件的Sweet Alert? - Sweet Alert with stateful react component?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM