0

I am using react/redux/material ui and normally through out my website the components work fine. One 1 page there is something very very wierd going on.

I create a component like this:

class MyOwnComponent extends Component {
  doSomething = (id) => {
    alert('doSomething: id = ' + id )
  }

  render() {
    return (
      <RaisedButton secondary={true} label={'My label'} onTouchTap={this.doSomething(id)}/>
    )
  }
}

I have a raisedbutton from material ui and put it in the render method.

The thing is that when the page loads with the component in it the doSomething method is called. Even though it is only called in the onTouchTap in raisedbutton. Almost as if a bug in the raisedbutton is calling the onTouchTap method immediately instead when the button is clicked.

Does any body have a explanation for this really strange behaviour?

Thanks

M. Jansen
  • 15
  • 2

3 Answers3

2

You are giving to onTouchTap void, because that's what this.doSomething(id) returns .

this.doSomething(id) 

is executed the firs time MyOwnComponent is rendered.

Instead you should do this :

class MyOwnComponent extends Component {
  doSomething = () => {
    const {id}  = this.props.object;
    alert('doSomething: id = ' + id )
  }

  render() {
    return (
      <RaisedButton secondary={true} label={'My label'} onTouchTap={this.doSomething}/>
    )
  }
}
Anis Smail
  • 707
  • 7
  • 22
  • @M.Jansen It's true that using arrow functions or binding in JSX is a bad practice as explained in this [answer](http://stackoverflow.com/questions/36677733/why-jsx-props-should-not-use-arrow-functions) I updated the answer to not use arrow functions. – Anis Smail May 02 '17 at 09:12
  • That did it :). Thanks. If I want to learn more about how this works under the hood, why I can't just supply a function with parameter, what should I look for? Is this new javscript, ES6 or react javascript format? – M. Jansen May 02 '17 at 09:32
  • You can't supply a function with parameters just because when you do this it calls the function and assign its return value. You can call bind to pass the parameter : this.doSomething.bind(null, id). Can you accept my answer ? :) – Anis Smail May 02 '17 at 09:36
  • Makes sense. I am used to plain Javascript where a button onclick calls a function which may have parameters. – M. Jansen May 02 '17 at 11:31
1

The problem was that the return value of doSomething() function is returned and assigned to onTouchTap. Instead you should just pass the function name, without paranthesis.

One solution can be this.

class MyOwnComponent extends Component {
  doSomething = () => {
   alert('doSomething: id = ' + this.props.object.id );
  }
  render() {
   return (
     <RaisedButton secondary={true} label={'My label'} onTouchTap=
      {this.doSomething}/>
   );
  }

}

Alternatively you can use also use

<RaisedButton secondary={true} label={'My label'} onTouchTap={()=> 
   this.doSomeThing(id) /> // eslint-disable-line
JiN
  • 818
  • 1
  • 7
  • 14
0

I tried your sollution. However when I use onTouchTap={() => this.doSomething(id)} the page wont load because the browser says JSX props should not use arrow functions.

And the id is from the props. At the top of the render method I say

const { id } = this.props.object
M. Jansen
  • 15
  • 2