If you put the helper function inside the component function, everytime the component function gets executed, it will create a new instance of the helper function and after the function was executed the instance possibly gets garbage collected. So typically I would put it outside.
Of course there are exceptions, if you use an arrow function, you might need the lexical scope and therefor put it inside the component function, but if it's a pure function, I would say it should go outside.
Answer from gwildu on Stack OverflowSo, as an example, I have a function that simply maps over an input array and returns an array. This function does not interact with the UI or call any other functions at all.
Where should this function go? Should I declare it within the Component? Should I make a separate function() declaration outside the Component at the bottom of the file?
If it's a function that is used in many files I would probably create a helper file to use it, but what if it's specific to this Component?
Just wondering what best practice is and why.
reactjs - Helpers in stateless functional components - Stack Overflow
Initialise helper class in a react functional component
Does having a lot of inner 'helper' functions inside a functional stateless react component will result in worse performance
reactjs - How to create helper file full of functions in react native? - Stack Overflow
Videos
If you put the helper function inside the component function, everytime the component function gets executed, it will create a new instance of the helper function and after the function was executed the instance possibly gets garbage collected. So typically I would put it outside.
Of course there are exceptions, if you use an arrow function, you might need the lexical scope and therefor put it inside the component function, but if it's a pure function, I would say it should go outside.
If you intend to reuse the helper function, put it outside the stateless component function, either in same file or another, and export it:
export const myHelper = (value) => {
// Insert logic
};
Otherwise, it's up to you to decide - whatever makes sense to keep things organized.
With your first example, a new function object has to be created each time Foo runs. So that's memory churn you don't need unless the JavaScript engine can optimize it out. (Like almost all performance concerns, of course, it's the kind of thing to worry about when you have a performance problem. Although if you're doing this in a lot of small components, it can add up.)
Depending on what helper needs, you could define it outside your SFC and just use it within it.
// I'm assuming this is in a module, so it's not a global
const helper = () => {
doSomething()
}
const Foo = () => {
// Presumably you use `helper` here somewhere
return (<View />)
}
If for some reason you're not using modules (!!), to avoid helper being global, you'd do the usual scoping thing. Perhaps:
const Foo = (() => {
const helper = () => {
doSomething()
}
return () => {
// Presumably you use `helper` here somewhere
return (<View />)
}
})()
Your coworker is technically correct that the inner functions will be instantiated and bound on each call to render(), but unless you are rendering a very large number of components very frequently (as the result of rapid state changes or something), the total cost should be negligible.
Quick note: You are importing a class, you can't call properties on a class unless they are static properties. Read more about classes here: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes
There's an easy way to do this, though. If you are making helper functions, you should instead make a file that exports functions like this:
export function HelloChandu() {
}
export function HelloTester() {
}
Then import them like so:
import { HelloChandu } from './helpers'
or...
import functions from './helpers'
then
functions.HelloChandu
An alternative is to create a helper file where you have a const object with functions as properties of the object. This way you only export and import one object.
helpers.js
const helpers = {
helper1: function(){
},
helper2: function(param1){
},
helper3: function(param1, param2){
}
}
export default helpers;
Then, import like this:
import helpers from './helpers';
and use like this:
helpers.helper1();
helpers.helper2('value1');
helpers.helper3('value1', 'value2');
IMHO, put helpers outside. Your cons are not cons
- If a helper is specific to a component, then it is not a helper.
- The DRY principle refers to repeating logic rather than data
If your helper function belongs only to one component and are not used outside even not use external resourses, only some kind of specially render logic, you can treat as component logic.
If your helper function belongs to multiples components or projects, you will be breaking DRY rules repeting code and maybe adding logic that dont belong to component itself. So makes sense to create a helper function outsite component and treat the values that come from context and hooks as arguments of external function library, that can be reused over several projects.
So whenever a functional component re-renders (state changes), everything in the component gets re-created. So with that in mind... if there's a helper function that's pure, should we always put it outside of the component (not inside component's scope)? Is there actual performance benefit in not having this function always recreated on render? I always thought it was for readability. Example below would only re-render if the parent component re-renders but that's beside the point:
const sum = (a, b) => a + b;
const addComponent = ({num1, num2}) => {
return <div>{sum(num1, num2)}</div>
}
vs
const addComponent = ({num1, num2}) => {
const sum = (a, b) => a + b;
return <div>{sum(num1, num2)}</div>
}
The real performance benefit comes to play when you pass the function as prop to a child. Like this
const AddComponent = ({num1, num2}) => {
const sum = (a, b) => a + b;
return <Sum calculate={sum}>
}
Now the Sum component renders each time together with the parent. By moving the function outside the component it doesn't anymore. So if the child is complex you may have a considerable performance benefit.
Edit: as mentioned correctly below the child component always re-renders when the parent re-renders. So to get the performance benefit described above the child component needs to be wrapped in React.memo like this
React.memo(Sum)
The performance boost will be minimal. But I would argue that it is still valuable thing to do because if you'll place this function outside component, you can then unit test it in isolation. At my current job we have set a convention that there should be no functions inside component (except really basic ones which result will be in 100% represented by ui) and all logic should be either placed outside component or inside custom hook created for this component. Thanks to this approach we can test component by mocking one hook, test all pure functions one by one and then test the hook in isolation. It's really much easier this way to write many tests that will cover every case than writing tests that are based only on visual result.
» npm install react-component-helpers
In functional components, what's the difference between putting helper functions inside and putting them outside the component's body?
When you're defining a function like this
const func = () => {};
You're creating a new variable.
const createFunc = () => {
const func = () => {};
return func;
}
createFunc() !== createFunc();
This means that every time you create a new function during rendering, it's a new function, different from the previous one. This can mess up some checks, like the dependency arrays in hooks, or checks for React.memo components or PureComponent-s. That's why people use useCallback if a function is in the component body.
The different is referential equality! Outside of the component, the function won't chance (hash code).