47

Issue: I have a lot of small helper functions that don't necessarily need to live in a component(or maybe they can but they will make that component bloated with a lot of code).My lazy side just wants to just let those all just be some sort of global functions that the components can call.I really want to make good ReactJs code.

Question: What are the best practices in terms of global helper functions in Reactjs? Should I force them into some sort of component or just shove them into the other components?

Basic Example:

function helperfunction1(a, b) {
    //does some work
    return someValue;
}

function helperfunction2(c, d) {
    //does some work
    return someOtherValue;
}

function helperfunction3(e, f) {
    //does some work
    return anotherValue;
}

function helperfunction4(a, c) {
    //does some work
    return someValueAgain;
}


var SomeComponent =
    React.createClass({

        //Has bunch of methods

        //Uses some helper functions

        render: function () {

        }

    });

var SomeOtherComponent =
    React.createClass({

        //Has bunch of methods

        //Uses some helper functions

        render: function () {

        }

    });
George Kagan
  • 5,913
  • 8
  • 46
  • 50
Nick Pineda
  • 6,354
  • 11
  • 46
  • 66

6 Answers6

57

You can export multiple functions from a file, no React needed per se:

Helpers.js:

export function plus(a, b) {
  return a + b;
}

export function minus(a, b) {
  return a - b;
}

export function multiply(a, b) {
  return a * b;
}

export function divide(a, b) {
  return a / b;
}

You can then import the functions you need:

import { multiply, divide } from './Helpers'
Michiel
  • 2,143
  • 1
  • 21
  • 21
  • 4
    I had to use './Helpers.js' but this still helped me. – Chris Farr Nov 01 '18 at 21:37
  • calling it in by `onClick={(e) => {exportTableToExcel("ParkSorguTable", "ParkSorgu")}}` causes `TypeError: Object(...) is not a function` importing as `import exportTableToExcel from '@/util/helper.js';` – efirat Dec 14 '19 at 15:04
  • I need to import inside curly brackets! Thanks `import {exportTableToExcel} from '@/util/helper.js';` – efirat Dec 14 '19 at 15:06
  • 1
    @efirat: If you only have 1 function you can also do this: `export default function myFunction () { /* ... */ }` and then: `import myFunction from './myFunction'`. – Michiel Dec 19 '19 at 11:32
  • 3
    A better approach is to put all of those functions into a closure that has multiple return members (one for each function) and then export the entire closure. That way you have access to all of the functions without having to import each one separately. – Johann Mar 05 '20 at 19:17
9

You can use a module-bundling tool like Webpack or Browserify for that. Put your reusable functions in a CommonJS module.

Do not use Mixins, they will probably be deprecated in next versions of React as there's no standard way to declare mixins in React with ES6 syntax and they prefer to wait for ES7 that will probably standardize mixins. And there's no point coupling your reusable code to React unless it uses React lifecycle's methods.

Oli C
  • 1,120
  • 13
  • 36
Sebastien Lorber
  • 89,644
  • 67
  • 288
  • 419
  • 1
    Could you post a short example, please? Would you still leave the functions in the global scope but require them through a module? – Simon May 30 '16 at 12:27
  • 2
    I don't understand what you ask for @Simon. Just put your helper code in another file: `export function help(someArg) { return "something" }` and require that where you need it. – Sebastien Lorber May 30 '16 at 13:22
1

You can use modulejs. or you can use mixins (https://facebook.github.io/react/docs/reusable-components.html#mixins)

Sample for mixins: https://jsfiddle.net/q88yzups/1/

var MyCommonFunc = {
    helperFunction1: function() {
       alert('herper function1');
    },
    doSomething: function(){
        alert('dosomething');
    }
}

var Hello = React.createClass({
    mixins: [MyCommonFunc],
    render: function() {
        this.doSomething();
        return <div onClick={this.helperFunction1}>Hello {this.props.name} </div>;
    }
});

React.render(<Hello name="World" />, document.getElementById('container'));
wilson
  • 11
  • 3
1

Just another option, if you don't want to split into a separate module, you could create a private method in your parent component like below and use freely within this component or pass to the child components via props..

var YourComponent = React.createClass({

    globalConfig: function() {
        return {
            testFunc: function () {
                console.log('testing...');
            },
        };
    }(),

    ......
    render: function() {
        this.globalConfig.testFunc(); // use directly

        <ChildComponent testFunc={this.globalConfig.testFunc} /> // pass to child
    .....

All untested, but that's the idea...

curv
  • 3,796
  • 4
  • 33
  • 48
1

Use a React context to do something like this. It's built for this exact use case; Doc: https://reactjs.org/docs/context.html

Akshay K Nair
  • 1,107
  • 16
  • 29
0

react can be avoided altogether, like Michiel says though a slight improvement would be to put all those pure js functions in a single fle then connect it to your html start page and the functions will be available everywhere:

just with a

<script src='./global-func.js' ></script>

its a dirty hack but it works ;)

you wont have to import the file into every component class you make

Pierce
  • 1
  • 2