Your Web News in One Place

Help Webnuz

Referal links:

Sign up for GreenGeeks web hosting
May 1, 2021 03:41 pm GMT

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!

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?


Original Link: https://dev.to/alekseiberezkin/2-javascript-memory-concerns-for-react-developers-19i1

Share this article:    Share on Facebook
View Full Article

Dev To

An online community for sharing and discovering great ideas, having debates, and making friends

More About this Source Visit Dev To