Я пытаюсь передать запрос от дочернего компонента к родительскому компоненту, где мой родительский компонент может выполнить вызов api. Я поискал в Интернете и обнаружил, что люди создают функцию в родительском компоненте и вызывают ее в дочернем компоненте для передачи данных через реквизиты, но мой код не работает. Когда я пробую предложенные решения, я получаю сообщение о том, что моя функция getArtistName () не определена в дочернем компоненте. Я новичок в реакции и хотел бы знать, почему и как работает этот код.

Родительский компонент

class App extends Component {

  state = {
    items: [],
    didLoad: false,
    query: ''
  }

  async grabArtistInfo() {
    const url = `https://api.songkick.com/api/3.0/artists/4971683/calendar.json?apikey=${myKey}`
    const response =  await fetch(url);
    const data = await response.json();
    this.setState({items:data, didLoad:true});
    console.log(this.state.items)
  }

  async componentDidMount() {
    this.grabArtistInfo()   
  }

  getArtistName = (artist) => {
    this.setState({query: artist});
    console.log(this.state.query);
  }

  render() {
    if (this.state.didLoad == true) {
      return (
        <div className="App">
          <Header q = {(fromChild) => this.getArtistName(fromChild)} />
          <Element name = 'Featured'>
            <Featured 
              deadline = {this.state.items.resultsPage.results.event[0].start.datetime}
            />
          </Element>
          <Element name = "Venue_info">
            <VenueInfo/>
          </Element>
          <Element name = "Highlights">
            <Highlights/>
          </Element>
          <Element name = "Pricing">
            <Pricing/>
          </Element>
          <Element name = "Location">
            <Location 
              lng = {this.state.items.resultsPage.results.event[0].venue.lng} 
              lat = {this.state.items.resultsPage.results.event[0].venue.lat}
              desc = {this.state.items.resultsPage.results.event[0].venue.displayName}
              locationDetails = {this.state.items.resultsPage.results.event[0].location.city}
              />
          </Element>
          <Footer/>
        </div>
      );
    }
    else {
      return (
        <div>Loading ... </div>
      )
    }
  }
}

export default App;

Дочерний компонент

class Header extends Component {

    constructor(props) {
        super(props);
        this.state = {
            drawerOpen: false,
            headerShow: false,
            fromChild: ''
        };
    }



    componentDidMount(){
        window.addEventListener('scroll',this.handleScroll);
    }


    handleScroll = () => {
        if(window.scrollY > 0){
            this.setState({
                headerShow: true
            })
        } else {
            this.setState({
                headerShow: false
            })
        }
    }


    toggleDrawer = (value) => {
        this.setState({
            drawerOpen: value
        })
    }

    handleChange = (e) => {
        if(e.keyCode == 13){
            this.setState({query: e.target.value})
            this.props.getArtistName(this.state.query)
        } else {
        this.setState({ query: e.target.value });
        }
    }

    render() {
        return (
            <AppBar
                position="fixed"
                style={{
                    backgroundColor: this.state.headerShow ? '#2f2f2f' : 'transparent',
                    boxShadow: 'none',
                    padding: '10px 0px'
                }}
            >
                <Toolbar>

                    <div className="header_logo">
                        <div className="font_righteous header_logo_venue">Musical Events</div>
                        <div className="header_logo_title">Countdown</div>
                    </div>
                    <div style = {searchStyle}>

                        <InputBase
                            placeholder= "Search…"
                            inputProps= {{ 
                                'aria-label': 'search',
                                style:{color: "white"}
                            }}
                            value = {this.state.query}
                            onChange = {this.handleChange}
                            onKeyDown = {this.handleChange}
                        >
                        </InputBase>
                    </div>
                    <IconButton
                        aria-label="Search"
                        color = "inherit"
                        onClick = {() => console.log(this.state.query)}
                    >
                        <SearchIcon/>
                    </IconButton>
                    <IconButton
                        aria-label="Menu"
                        color="inherit"
                        onClick={()=> this.toggleDrawer(true)}
                    >
                        <MenuIcon/>
                    </IconButton> 

                    <SideDrawer
                        open={this.state.drawerOpen}
                        onClose={(value)=> this.toggleDrawer(value)}
                    />


                </Toolbar>
            </AppBar>
        );
    }
}

export default Header;

Для справки я использую materialUI для создания панели поиска. Состояние запроса выполняет свою задачу, но передача его в родительский компонент оказывается довольно сложной задачей.

0
Jonathan Yuen 28 Окт 2019 в 10:33

1 ответ

Лучший ответ

Вы прошли getArtistName в q, поэтому вам нужно получить доступ через this.props.q

handleChange = (e) => {
        if(e.keyCode == 13){
            this.setState({query: e.target.value})
            this.props.q(this.state.query)
        } else {
        this.setState({ query: e.target.value });
        }
    }
1
akhtarvahid 28 Окт 2019 в 07:40