Skip to content

Instantly share code, notes, and snippets.

@arafathusayn
Last active March 18, 2023 12:46
Show Gist options
  • Save arafathusayn/99eeb1e9f5267015bb781602e2a934c7 to your computer and use it in GitHub Desktop.
Save arafathusayn/99eeb1e9f5267015bb781602e2a934c7 to your computer and use it in GitHub Desktop.
useEffect alternative for functional React components
import * as React from "react";
import { useState } from "react";
import withCleanup from "./withCleanup";
import withOnMount from "./withOnMount";
let loaded = false;
function Counter() {
const [count, setCount] = useState(0);
if (!loaded) {
console.log("1. Do something once regardless of mount-unmount.");
loaded = true;
}
return (
<div>
<button
onClick={() => {
setCount((v) => v + 1);
}}
>
Rerender {count}
</button>
</div>
);
}
export default withCleanup(
withOnMount(Counter, () => {
console.log("2. Do something on mount.");
}),
() => {
console.log("3. Do something on unmount.");
}
);
import * as React from "react";
type ComponentType<P> = React.ComponentClass<P> | React.FC<P>;
export default function withCleanup<P>(
WrappedComponent: ComponentType<P>,
cleanup: () => void
): ComponentType<P> {
return class extends React.Component<P> {
componentWillUnmount() {
cleanup();
}
render() {
return <WrappedComponent {...this.props} />;
}
};
}
import * as React from "react";
type ComponentType<P> = React.ComponentClass<P> | React.FC<P>;
export default function withOnMount<P>(
WrappedComponent: ComponentType<P>,
onmount: () => void
): ComponentType<P> {
return class extends React.Component<P> {
loaded: boolean;
constructor(props) {
super(props);
this.loaded = false;
}
componentDidMount() {
if (!this.loaded) {
this.loaded = true;
onmount();
}
}
render() {
return <WrappedComponent {...this.props} />;
}
};
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment