javascriptreactjsecmascript-6constantsreact-16

Order of 'const' variables in React Stateless Components


Say I have a simple React stateless component like so:

const myComponent = () => {
    const doStuff = () => {
        let number = 4;

        return doubleNumber(number);
    };

    const doubleNumber = number => {
        return number * 2;
    };

    return <div>Hello {doStuff()}</div>;
};

export default myComponent;

Based on the eslint error I receive, and my understanding of how 'const' works, I assumed that this component would not render, since the function 'doubleNumber()' is used by the function 'doStuff()' before it is initialized. However, whenever I use this component, it renders as expected - why doesn't it throw an exception? Does this mean the order of 'const' variables in React components can be whatever we like?


Solution

  • The reason the code works is because the body of doStuff isn't executed until it's invoked. Since doubleNumber happened to be defined before doStuff was called, everything is fine, but the code is correctly identified as brittle by the linter because the dependency inversion.

    The crash occurs only if you happened not to initialize doubleNumber by the time doStuff was called:

    const doStuff = () => doubleNumber(4);
    doStuff(); // ReferenceError: doubleNumber is not defined
    const doubleNumber = number => number * 2;
    

    which seems obvious here, but in more complex cases may not be so clear.

    const versus let should have no bearing on the linter's output because although they're hoisted, they cannot be accessed until initialized.

    The order can be whatever you like, assuming calls are only made once dependencies are available, but that doesn't make it a good idea (which is exactly what linting is supposed to identify).