Reputation: 3184
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
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