Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Are parameters needed for inner functions to access props + variables of a React Functional Components

I have a functional component that has a couple of functions inside of it. In the example below, the inner functions are function1 and function2. I am trying to figure out if i need to explicitly pass the functional component's props (prop1, prop2), as well as other declared variables within the functional component (variable1, variable2) into these inner functions. Here is an example:

import React from 'react'
import * as d3 from 'd3';

function MyFunction({prop1, prop2}) {
    const variable1 = '#333333';
    const variable2 = 'Jimmy';

    const function1 = () => {
        d3.select('g.g1')
            .append('rect')
            .attr('color', variable1)
    }

    const function2 = () => {
        d3.select('g.g2')
            .append('text')
            .text(prop1.label)
    }

    return (
        <svg>
            <g className='g1' />
            <g className='g2' />
        </svg>
    );
}

export default MyFunction;

It seems to simplify my code if I don't have to explicitly declare parameters for function1 and function2 to be able to use these props + other variables declared in the upper scope, however I am not sure if this is a bad practice, or if this will cause other issues with my code. Is this okay?

Edit

Wanted to note that this does, in fact, seem to work without any issues. My question is more a matter of - should I do this / is it okay / are there problems I may run into down the road doing this?

like image 784
Canovice Avatar asked Sep 07 '25 09:09

Canovice


1 Answers

Using a function in a function is perfectly fine. There are all kinds of articles you can read on if you should use useCallback. I'll talk about that in a second.

No, you don't need to pass the props to each function. The reason for this is closures and what it captures. Here is some reading on it under closures. Your arrow function closes over the props variable if they reference it. So nope, you don't need to pass it, and check out that link. And Chapter 2 if you really want to dig in depth.

As for performance, it's normally fine! Every time your component renders though, function1 and function2 will be redefined. They'll be the same exact function (unless d3 changes), but with a different reference, so the old function1 !== the new function1 even if they do the same thing. This is why that matters...

For a little more overhead though (per render of the component, possibly saving many renders of other components or useEffect executions), you can have react analyze if it should redefine function1 or function2 and if not, it keeps the same reference. This is what useCallback does. Honestly, I use useCallback if I'm ever unsure if the function will cause me issues. An example is when a child component has function1 passed in as a prop. That prop will ALWAYS be evaluated as a new value on every render of the parent because it's a new reference, unless you use useCallback.

like image 122
Diesel Avatar answered Sep 10 '25 03:09

Diesel