74

I have a React component

export default class Archive extends React.Component { 
   ...
}

componentDidMount and onClick methods partially use the same code, except for slight change in parameters.

Is it possible to create a function inside the component class so it can be reused in the scope of the component?

4 Answers 4

124

You can create functions in react components. It is actually regular ES6 class which inherits from React.Component. Just be careful and bind it to the correct context in onClick event:

export default class Archive extends React.Component { 

    saySomething(something) {
        console.log(something);
    }

    handleClick(e) {
        this.saySomething("element clicked");
    }

    componentDidMount() {
        this.saySomething("component did mount");
    }

    render() {
        return <button onClick={this.handleClick.bind(this)} value="Click me" />;
    }
}
Sign up to request clarification or add additional context in comments.

6 Comments

What if you want to do recursive call of a function? How do you call that within the function?
@Norfeldt as simple as non-recursive call, just call the method/function this.myMethod()
For me just this.handleClick works for me to invoke a custom function defined in my react component. What is this additional syntax .bind(this)? Why do we need it?
@RBT sure, it will invoke the function. The problem is that this inside the method will not be what you would expect. See more about it here stackoverflow.com/questions/33973648/…
@FedericoCapaldo bind the function only once, in constructor
|
38

Another way:

export default class Archive extends React.Component { 

  saySomething = (something) => {
    console.log(something);
  }

  handleClick = (e) => {
    this.saySomething("element clicked");
  }

  componentDidMount() {
    this.saySomething("component did mount");
  }

  render() {
    return <button onClick={this.handleClick} value="Click me" />;
  }
}

In this format you don't need to use bind

3 Comments

Can I try to access these local functions, from a different component?? I mean can we export such a function, actually I am getting error
I wouldn't recommend that. I would just create a function in another file, and call the function in both (or more) places. In my example above, I would add a saySomething.js and export saySomething there. Then in both of components you import saySomething and then call the function. The advantage of this approach is saySomething can be unit tested in separation and you have 2 independent components that just so happen using some same code instead of tangle them together
It's not even working for me this. I am getting saySomething is not a function on the very declaration line. I need to use old way of ES5 function() { ... } or declare the function in another file.
13

You can try this.

// Author: Hannad Rehman Sat Jun 03 2017 12:59:09 GMT+0530 (India Standard Time)

import React from 'react';
import RippleButton from '../../Components/RippleButton/rippleButton.jsx';

class HtmlComponents extends React.Component {

    constructor(props){
        super(props);
        this.rippleClickFunction=this.rippleClickFunction.bind(this);
    }

    rippleClickFunction(){
        //do stuff. 
        // foo==bar
    }

    render() {
      return (
         <article>
             <h1>React Components</h1>
             <RippleButton onClick={this.rippleClickFunction}/>
         </article>
      );
   }
}

export default HtmlComponents;

Yhe only concern is you have to bind the context to the function

Comments

4

With React Functional way

import React, { useEffect } from "react";
import ReactDOM from "react-dom";
import Button from "@material-ui/core/Button";

const App = () => {
  const saySomething = (something) => {
    console.log(something);
  };
  useEffect(() => {
    saySomething("from useEffect");
  });
  const handleClick = (e) => {
    saySomething("element clicked");
  };
  return (
    <Button variant="contained" color="primary" onClick={handleClick}>
      Hello World
    </Button>
  );
};

ReactDOM.render(<App />, document.querySelector("#app"));

https://codesandbox.io/s/currying-meadow-gm9g0

2 Comments

Is this actually ok? Or is there a performance overhead? I kinda assumed you'd have to declare the methods outside of the component function
I think you'd need to use useCallback to stop the function being redefined everytime. stackoverflow.com/questions/46138145/…

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.