3

I have component with button and 2 functions.Button component used in various components. And for some need one function for onclick event, for other - second. How can I change functions for onclick event? I'm using this answer, but always getting undefined in my components.

export default class MyButtonComponent extends Component {

constructor(props) {
    super(props);
    propTypes: {
        onClick: PropTypes.func
    };
    this.state = { loading: false, api_url: "http://localhost:8000" };
}

 static get DefaultProps() {
  return {
    onClick: this.firstFunction(event)
  }
}

firstFunction(){
/*some code*/
}

secondFunction(){
/*some code*/
}

render() {
    return (
        <LaddaButton
            loading={this.state.loading}
            onClick={this.props.onClick}
            className='submit'
            data-color="#eee"
            data-style={SLIDE_UP}
            data-spinner-size={30}
            data-spinner-color="#ddd"
            data-spinner-lines={12}
            data-url={this.props.url}
        >
            Отправить
        </LaddaButton>

    );
}

And in another component:

<FormGroup>
     <Col mdOffset={5} md={7}>
         <MyButtonComponent onClick={this.secondFunction} data-url="someurl.com"></MyButtonComponent>
     </Col>
</FormGroup>

Also tried add

onClick={e => this.secondFunction(e)} 

to button componentm but always getting error

_this2.secondFunction is not a function
Community
  • 1
  • 1
Simple runner
  • 445
  • 6
  • 19

2 Answers2

3

The problem looks to be with how you're using this - when you call this.secondFunction in the <FormGroup> element of your other component, it's looking for secondFunction in that component. You've defined secondFunction in MyButtonComponent, so it's coming back as undefined.

You could get around this by defining a single click handler in MyButtonComponent that chooses which function to call based on a prop that you can update externally. E.g.

function myClickHandler(e) {
    if(useFirst) {
        this.firstFunction(e);
    } else {
        this.secondFunction(e);
    }
}

Then you could change that property in the render method of your other component, e.g.

<FormGroup>
    <Col mdOffset={5} md={7}>
        <MyButtonComponent useFirst=false data-url="someurl.com"></MyButtonComponent>
    </Col>
</FormGroup>
Graham Harper
  • 487
  • 5
  • 11
2

Since you are passing secondFunction() as a prop to the MyButtonComponent component and hence it must not be defined in the MyButtonComponent component but in the component in which you have the below code

<FormGroup>
     <Col mdOffset={5} md={7}>
         <MyButtonComponent onClick={this.secondFunction} data-url="someurl.com"></MyButtonComponent>
     </Col>
</FormGroup>

In the MyButtonComponent you can reference it as this.props.onClick() but it must be defined in the calling component

Also you need to bind the function while passing it as a prop to the MyButtonComponent like

<FormGroup>
     <Col mdOffset={5} md={7}>
         <MyButtonComponent onClick={this.secondFunction.bind(this)} data-url="someurl.com"></MyButtonComponent>
     </Col>
</FormGroup>

Check the answer here to understand the flow better

Community
  • 1
  • 1
Shubham Khatri
  • 270,417
  • 55
  • 406
  • 400