2 JavaScript memory concerns for React developers

React provides a superb developer experience: you define states and props, combine components in a way you want — and everything magically updates yet stays consistent. But… What memory effects hide beneath this nice-looking code? Let’s see!


This content originally appeared on DEV Community and was authored by Aleksei Berezkin

React provides a superb developer experience: you define states and props, combine components in a way you want — and everything magically updates yet stays consistent. But... What memory effects hide beneath this nice-looking code? Let's see!

1. Class members: functions vs arrow functions

Here are two very similar classes. What's the difference?

class A {
    x() {
        console.log('Hi!')
    }
}

class B {
    y = () => console.log('Hi!')
}

Okay, okay you are right, y is this-bound ? But I wouldn't disturb you with such a trivial thing. There's an interesting memory implication I suggest you to spot.

⌛️

A.x resides on A prototype, and B.y copy resides on each B instance, meaning B instances consume more memory.

Writing the same using only functions makes this more prominent:

function A() {
}

A.prototype.x = function() {
    console.log('Hi!')
}

function B() {
    this.y = () => console.log('Hi!')
}

A instances are completely empty!

Why is it important?

When implementing React class components we often need this-bounded functions, and one possible option is an arrow function. In the following example each Button instance has its own handleClick member:

class Button {
    constructor(props) {
        this.props = props
    }
    render() {
        return <button onClick={this.handleClick} />
    }
    handleClick = () => console.log(this.props.message)
}

Is it a problem?

In 99% of cases it's not — an arrow function instance is not that big. Just make sure you don't use it unless you need it. For example, if handleClick calls some other class method, it's better be defined as a simple function:

class Button {
    // ...
    handleClick = () => this.logMessage()
    logMessage() {
        console.log(this.props.message)
    }
}

2. Inner functions

What will the following code print? Or, in other words, is inner function referentially the same at each run?

function outer() {
    function inner() {
        console.log('Hi!')
    }
    return inner
}

console.log(outer() === outer())

⌛️

The inner function is referentially different at each run, and the code outputs false.

Why is it important?

Inner functions are the common way to define handlers in React functional components:

function Button({message}) {
    function handleClick() {
        console.log(message)
    }
    return <button onClick={handleClick} />
}

In this example a new handleClick is created on each function run, i.e. on each component render.

Someone told me useCallback can fix this

function Button({message}) {
    const handleClick = useCallback(function(m) {
        console.log(m)
    }, [message])
    return <button onClick={handleClick} />
}

Now inner function(m) is created only when message changes, isn't it?

⌛️

No, useCallback can't override how JavaScript works, and function(m) is created at each component render.

Is it a problem?

Just like in previous example, it's fine in 99% of cases. However, if your handler doesn't need a closure over locals, you may define it outside the component:

function Button() {
    return <button onClick={handleClick} />
}

function handleClick() {
    console.log('Hi!')
}

Further reading

Official explanation on hooks performance

Thanks for reading this. Do you know other JavaScript memory concerns useful to keep in mind?


This content originally appeared on DEV Community and was authored by Aleksei Berezkin


Print Share Comment Cite Upload Translate Updates
APA

Aleksei Berezkin | Sciencx (2021-05-01T15:41:15+00:00) 2 JavaScript memory concerns for React developers. Retrieved from https://www.scien.cx/2021/05/01/2-javascript-memory-concerns-for-react-developers/

MLA
" » 2 JavaScript memory concerns for React developers." Aleksei Berezkin | Sciencx - Saturday May 1, 2021, https://www.scien.cx/2021/05/01/2-javascript-memory-concerns-for-react-developers/
HARVARD
Aleksei Berezkin | Sciencx Saturday May 1, 2021 » 2 JavaScript memory concerns for React developers., viewed ,<https://www.scien.cx/2021/05/01/2-javascript-memory-concerns-for-react-developers/>
VANCOUVER
Aleksei Berezkin | Sciencx - » 2 JavaScript memory concerns for React developers. [Internet]. [Accessed ]. Available from: https://www.scien.cx/2021/05/01/2-javascript-memory-concerns-for-react-developers/
CHICAGO
" » 2 JavaScript memory concerns for React developers." Aleksei Berezkin | Sciencx - Accessed . https://www.scien.cx/2021/05/01/2-javascript-memory-concerns-for-react-developers/
IEEE
" » 2 JavaScript memory concerns for React developers." Aleksei Berezkin | Sciencx [Online]. Available: https://www.scien.cx/2021/05/01/2-javascript-memory-concerns-for-react-developers/. [Accessed: ]
rf:citation
» 2 JavaScript memory concerns for React developers | Aleksei Berezkin | Sciencx | https://www.scien.cx/2021/05/01/2-javascript-memory-concerns-for-react-developers/ |

Please log in to upload a file.




There are no updates yet.
Click the Upload button above to add an update.

You must be logged in to translate posts. Please log in or register.