9

I want to pass a function to a component as a prop and use it in its render function, I seem to be missing a key concept here.

For example

index.jsx

render(<MyComponent d={data} showName = {d => d.name + ' ' + d.surname}/>, document.getElementById('app'));

MyComponent.jsx

class MyComponent extends React.Component {
    render() {
        return <h1>if (typeof this.props.showName === 'function') {
            //call this.props.showName(d)
        }
    }
}

edit

I want the showName prop to be either a function or a value and the component doesn't need to know about it beforehand.

edit2

On second thought, I think I'll build a component so it can use both a function and a value as a prop, but keep them separate so that I can validate them better. E.g. I'll either use

<MyComponent value="some value"/> 

or

<MyComponent calculatedValue = {// a function}/>
eagerMoose
  • 1,123
  • 5
  • 13
  • 35

6 Answers6

12

Write it like this:

checkMethod(){
    if(typeof(this.props.showName) === 'function') {
        //call this.props.showName(d);
        return null;
    }else{
        return this.props.showName;
    }    
}

class MyComponent extends React.Component {
    render() {
        return 
            <h1>
                {this.checkMethod()}
            </h1>
        }
    }
}
Mayank Shukla
  • 100,735
  • 18
  • 158
  • 142
4
class MyComponent extends React.Component {
    render() {
        return <h1>if (typeof this.props.showName === 'function') {
            //call this.props.showName(d)
        }
    }
}

Your above code seems fine. But your approach is wrong.

You need to validate props using propTypes

MyComponent .propTypes = {
showName : React.PropTypes.func
};

Here is the other checks,

propArray: React.PropTypes.array.isRequired,
   propBool: React.PropTypes.bool.isRequired,
   propFunc: React.PropTypes.func,
   propNumber: React.PropTypes.number,
   propString: React.PropTypes.string,
   propObject: React.PropTypes.object

React.PropTypes has moved into a different package since React v15.5. Please use the prop-types library instead.

import PropTypes from 'prop-types';

class Greeting extends React.Component {
  render() {
    return (
      <h1>Hello, {this.props.name}</h1>
    );
  }
}

Greeting.propTypes = {
  name: PropTypes.string
};
Thomas Smyth
  • 512
  • 3
  • 9
  • 36
Ved
  • 11,837
  • 5
  • 42
  • 60
3

https://facebook.github.io/react/docs/typechecking-with-proptypes.html

You can do it like this and if it's not a function it will tell you:

     MyComponent.propTypes = {
           showName: React.PropTypes.func.isRequired
     };

This is the react way to do it ;)

Edit: I got it now, you can do an assertion on the prop by calling it with an argument, if the assertion fails, you'll know it's not a function. Check this package on npm, it's easy to use it out of the box

https://www.npmjs.com/package/assert

Razvan Alex
  • 1,706
  • 2
  • 18
  • 21
  • Thanks. What if my component does not know in advance what the function will be called (or whether a prop will in fact be a function or not)? I'm trying to build a component which is flexible in that way, I'll edit my question. – eagerMoose Feb 13 '17 at 08:53
  • Check my edit for, assertion is the key for a more advanced use – Razvan Alex Feb 13 '17 at 08:56
  • 1
    I think I'll use this approach and modify my logic a bit. I'll either use a value or a function and just name the props differently (e.g. val, valFunc) and check which is passed. Thanks! – eagerMoose Feb 13 '17 at 09:10
2

If you don't want to use propTypes for whatever reason , you could use this, this is simple JavaScript :

function isFunction(functionToCheck) {
 var getType = {};
 return functionToCheck && getType.toString.call(functionToCheck) === '[object Function]';
}

source

Community
  • 1
  • 1
GhaziBenDahmane
  • 548
  • 3
  • 15
1

Have you tried React.PropTypes.func ?

https://facebook.github.io/react/docs/typechecking-with-proptypes.html

Faalsh
  • 128
  • 2
  • 8
  • 4
    I would steer away from answer with "Have you tried" or "Try" because it becomes more of a comment than a specific answer (it leaves some uncertainty about your response) – Callum Linington Feb 13 '17 at 12:18
0

My component needs to check if this.props.update is a function. Not sure if it's a right solution, but it definitely works in my case:

if ("update" in this.props) {
     this.props.update(data);
}
Mike Gordo
  • 121
  • 1
  • 4