Skip to content

Commit

Permalink
using useEffectOnce hook to not render twice with React Strict mode
Browse files Browse the repository at this point in the history
  • Loading branch information
maxeth committed Aug 20, 2022
1 parent 3cb3f77 commit 956706f
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 3 deletions.
2 changes: 2 additions & 0 deletions example/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -32,3 +32,5 @@ yarn-error.log*

# vercel
.vercel

package-dev.json
9 changes: 6 additions & 3 deletions src/components/TypeAnimation/index.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import React, { useRef, useEffect, memo, HtmlHTMLAttributes } from 'react';
import { type, type as typeloop } from '../../typical';

import styles from './index.module.css';
import { useEffectOnce } from '../../hooks/useEffectOnce';

type Speed =
| 1
Expand Down Expand Up @@ -159,7 +159,7 @@ const TypeAnimation: React.FC<TypeAnimationProps &
}
}

useEffect(() => {
useEffectOnce(() => {
if (repeat === Infinity) {
type(typeRef.current, speed, ...sequence, typeloop);
} else if (typeof repeat === 'number') {
Expand All @@ -173,12 +173,15 @@ const TypeAnimation: React.FC<TypeAnimationProps &
} else {
type(typeRef.current, speed, ...sequence);
}
return () => {
typeRef.current;
};
});

const Wrapper = wrapper;
return <Wrapper style={style} className={finalClassName} ref={typeRef} />;
};

export default memo(TypeAnimation, (_, __) => {
return true; // IMMUTABLE!
return true; // IMMUTABLE
});
32 changes: 32 additions & 0 deletions src/hooks/useEffectOnce.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import { useEffect, useRef, useState } from 'react';

export const useEffectOnce = (effect: () => void | (() => void)) => {
const effectFn = useRef<() => void | (() => void)>(effect);
const destroyFn = useRef<void | (() => void)>();
const effectCalled = useRef(false);
const rendered = useRef(false);
const [, setVal] = useState<number>(0);

if (effectCalled.current) {
rendered.current = true;
}

useEffect(() => {
if (!effectCalled.current) {
destroyFn.current = effectFn.current();
effectCalled.current = true;
}

setVal(val => val + 1);

return () => {
if (!rendered.current) {
return;
}

if (destroyFn.current) {
destroyFn.current();
}
};
}, []);
};

0 comments on commit 956706f

Please sign in to comment.