Tom Jackson
Tom Jackson

Reputation: 515

Having trouble passing parent function to child component

Using info on StackOverflow, I've tried to pass a parent function to a child component via props; however, I keep running into errors when doing so. To simplify, here is my parent function:

class App extends Component {

  constructor(props) {
    super(props)
    this.state = {
      dailyPreloadMetrics: null,
      queryResults: [0,0],
    }
    this.handleChange = this.handleChange.bind(this);
    this.handleSubmit = this.handleSubmit.bind(this);
  }

   handleChange(event) {
    this.setState({ [event.target.name]: event.target.value });
  }

  onClick(event) {
    const value = event.target.value;
    this.setState({isHidden: true});
    fetch('http://localhost:5000/kw-finder', {
      method: 'POST',
      headers: {
      'Accept': 'application/json',
      'Content-Type': 'application/json'
    },
      body: JSON.stringify({'firstParam': event.target.value,
                            'secondParam' : 300000})
    }).then(response => {
        console.log(response)
        return response.json()
      })
      .then(json => {
        console.log(json)
        this.setState({queryResults: JSON.parse(json['query_results']),
                       dailyPreloadMetrics: JSON.parse(json['keyword_data']),
                       })
      })
  }


  render() {
    return (
      <div className="App">
      <QueryResultButtons data={this.state.queryResults}
                          onClick={this.onClick}
                          />
      </div>
    )
  }
}

export default App

My Child component is as follows:

class DynamicButton extends React.Component {

  constructor(props) {
    super(props)
    this.state = {
      secondParam: this.props.audienceMax
      }
  }


  render() {
    const {
      data
    } = this.props
    const row = this.props.data && data.map((data) =>
        <Button style={{margin: "10px"}}
                value={data}
               onClick={e => this.props.onClick(e)}
                name='value'
                >
        </Button>

        )
    return (row)
  }
}

class QueryResultButtons extends React.Component {
  render() {
    return (
               <div>
                  <h1>Did you mean any of these instead?</h1>
                  <DynamicButton data={this.props.data && this.props.data}/>
              </div>
    )
}
}

export default QueryResultButtons

Basically I am trying to pass a function - onClick - from the parent to the two levels of child components (down to the DynamicButton Child Component). However, when I try this action, I get an error message stating: _this3.props.onClick is not a function. It seems the Child component isn't picking up the parent function but not sure what I'm doing wrong here...

Upvotes: 0

Views: 32

Answers (2)

user9408899
user9408899

Reputation: 4540

DynamicButton component is not direct child of App component, it is grandchild. So you have to pass onClick function from child component (QueryResultButtons) to grandchild component (DynamicButton) as well.

So, replace you QueryResultButtons with this:

class QueryResultButtons extends React.Component {
  render() {
    return (
      <div>
        <h1>Did you mean any of these instead?</h1>
        <DynamicButton
          data={this.props.data && this.props.data}
          onClick={this.props.onClick}
        />
      </div>
    );
  }
}

Upvotes: 1

rMonteiro
rMonteiro

Reputation: 1666

When you insert the QueryResultButtons component you are passing the onClick function like onClick={this.onClick} but when you call the DynamicButton you are not passing the onClick function:

<DynamicButton data={this.props.data && this.props.data}/>

Try this:

<DynamicButton data={this.props.data && this.props.data} onClick={this.props.onClick}/>

The QueryResultButtons should be:

class QueryResultButtons extends React.Component {
  render() {
    return (
               <div>
                  <h1>Did you mean any of these instead?</h1>
                  <DynamicButton data={this.props.data && this.props.data}
                                 onClick={this.props.onClick}
                  />
              </div>
    )
}
}

Upvotes: 1

Related Questions