Nerdragen
Nerdragen

Reputation: 3184

What is the proper way of initializing a class in React?

This is more of a theory and best practice questions versus as opposed to a how-to question, but what is the proper way of initializing a class in a React component and maintaining that singular instance throughout the component's lifecycle? For example, consider this class:

// MyClass.ts
class MyClass {
    constructor(){
      console.log('Initialized MyClass');
    }
}

And the following 2 methods:

// Test.tsx
import React, { memo } from 'react';

const myClass = new MyClass();

const Test = memo(() => {
  // I can use myClass here
  return null;
});

export default Test;

This works, but if I import this component; even if I don't use it, the console statement gets printed. (By use, I mean I dont do <Test /> anywhere)

// Test.tsx
import React, { memo } from 'react';

const Test = memo(() => {
  const myClass = new MyClass();
  // I can use myClass here
  return null;
});

export default Test;

This also works, except every time Test get's re-rendered, I get the console log statement printed.

I've even tried to solve both these problems (MyClass getting initialized even when not being used, and MyClass being re-initialized on every re-render) by using useRef since that's supposed to maintain state through an instance's lifecycle

// Test.tsx
import React, { memo, useRef } from 'react';

const Test = memo(() => {
  const myClass = useRef<new MyClass()>;
  return null;
});

export default Test;

But this has the same problem as method 2.

Upvotes: 1

Views: 2014

Answers (1)

AKX
AKX

Reputation: 168903

If you want to initialize your MyClass only once per your program's lifetime, make it a singleton:

class MyClass {
 // ...
}
let instance: MyClass | null = null;

// Never do `new MyClass()`, always call this.
export function getMyClass() {
  if(!instance) instance = new MyClass();
  return instance;
}

If you want to initialize one MyClass per component, use a read-only state atom with a lazy initializer function:

function MyComponent() {
  const [myClass] = React.useState(() => new MyClass());
}

Upvotes: 4

Related Questions