将子级数据传递给父级时未定义函数

时间:2019-10-28 07:33:47

标签: reactjs material-ui

我正在尝试将查询从子组件传递到父组件,在此父组件可以完成api调用。我在网上搜索过,发现人们已经在父组件中创建了一个函数,并在子组件中调用了该函数,以通过prop传递数据,但是我的代码无法正常工作。当我尝试建议的解决方案时,我得到一个调用,说我的功能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来创建搜索栏。查询状态已实现其目的,但将其传递给父组件却证明是颇具挑战性的

1 个答案:

答案 0 :(得分:1)

您在q中传递了getArtistName,因此您需要通过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 });
        }
    }