I came across posts where people mention useEffect
and even give some great examples, but I cannot find any real documentation. Also I grepped node_modules/preact
dir and there is no mention of useEffect
in the entire code base. Is this a separate module? Or I got the wrong version of preact (8.4.2)? Please explain and give a complete working example.
useEffect is primarily about accessing the Lifecycle Methods in a FunctionalComponent.
Preact ClassComponents have direct access to the Lifecycle methods, but FunctionalComponents do not.
Therefore, useEffect()
acts as all the Lifecycle Methods rolled into one.
For example: (Full example using Preact/Typescript)
In a ClassComponent you can load data via the ComponentDidMount
lifecycle method:
import { h, Component } from 'preact';
import * as style from './style.scss';
import { get } from '../../../utils/ajax';
import { ExampleDataObject } from '../types';
interface ComponentNameProps {
id: number;
}
interface ComponentNameState {
data: ExampleDataObject;
}
export class ComponentName extends Component<ComponentNameProps, ComponentNameState> {
public render ({ id }: ComponentNameProps, { data }: ComponentNameState) {
return (
<div class={style.container}>
{JSON.stringify(data)}
</div>
);
}
public componentDidMount(): void {
get(`/getData?id=${id}`).then((d) => {
this.setState({ data: d });
});
}
}
In a FunctionalComponent, the same effect can be achieved thus:
import { h, FunctionalComponent } from 'preact';
import * as style from './style.scss';
import { useState, useEffect } from 'preact/hooks';
import { get } from '../../../utils/ajax';
import { ExampleDataObject } from '../types';
interface ExampleProps {
id: number;
}
export const Example: FunctionalComponent<ExampleProps> = ({id}) => {
const [data, setData] = useState<ExampleDataObject | undefined>;
useEffect(() => {
get<ExampleDataObject>(`/getData?id=${id}`)
.then((d) => {
setData(d);
});
}, [id]);
return (
<div class={style.ExampleWrapper}>
{data !== undefined && (
JSON.stringify(data)
)};
</div>
);
}
Reminder: (for those using VSCode - which should be everyone-in-the-know):
VSCode will often do the import lines for you (i.e. using the Quick Fix helper) - but it often gets the import line wrong for useState / useEffect (it will add /src to the end, which doesn't work). So remember to double-check imports for these two.
WRONG:
import { useState, useEffect } from 'preact/hooks/src';
CORRECT:
import { useState, useEffect } from 'preact/hooks';
Hooks were released as part of React 16.8
. Preact hooks are in beta as of version 10. You can get access to them by updating Preact to the latest beta with npm install [email protected]
Usage,
import { useState } from 'preact/hooks'
export function Demo(props) {
const [count, setCount] = useState(0)
return <button onClick={() => setCount(c => c+1)}>{count}</button>
}
useEffect is primarily about accessing the Lifecycle Methods in a FunctionalComponent.
Preact ClassComponents have direct access to the Lifecycle methods, but FunctionalComponents do not.
Therefore, useEffect()
acts as all the Lifecycle Methods rolled into one.
For example: (Full example using Preact/Typescript)
In a ClassComponent you can load data via the ComponentDidMount
lifecycle method:
import { h, Component } from 'preact';
import * as style from './style.scss';
import { get } from '../../../utils/ajax';
import { ExampleDataObject } from '../types';
interface ComponentNameProps {
id: number;
}
interface ComponentNameState {
data: ExampleDataObject;
}
export class ComponentName extends Component<ComponentNameProps, ComponentNameState> {
public render ({ id }: ComponentNameProps, { data }: ComponentNameState) {
return (
<div class={style.container}>
{JSON.stringify(data)}
</div>
);
}
public componentDidMount(): void {
get(`/getData?id=${id}`).then((d) => {
this.setState({ data: d });
});
}
}
In a FunctionalComponent, the same effect can be achieved thus:
import { h, FunctionalComponent } from 'preact';
import * as style from './style.scss';
import { useState, useEffect } from 'preact/hooks';
import { get } from '../../../utils/ajax';
import { ExampleDataObject } from '../types';
interface ExampleProps {
id: number;
}
export const Example: FunctionalComponent<ExampleProps> = ({id}) => {
const [data, setData] = useState<ExampleDataObject | undefined>;
useEffect(() => {
get<ExampleDataObject>(`/getData?id=${id}`)
.then((d) => {
setData(d);
});
}, [id]);
return (
<div class={style.ExampleWrapper}>
{data !== undefined && (
JSON.stringify(data)
)};
</div>
);
}
Reminder: (for those using VSCode - which should be everyone-in-the-know):
VSCode will often do the import lines for you (i.e. using the Quick Fix helper) - but it often gets the import line wrong for useState / useEffect (it will add /src to the end, which doesn't work). So remember to double-check imports for these two.
WRONG:
import { useState, useEffect } from 'preact/hooks/src';
CORRECT:
import { useState, useEffect } from 'preact/hooks';
© 2022 - 2024 — McMap. All rights reserved.
React 16.8
. Preact hooks are in beta. github.com/preactjs/preact/pull/1302. – Nival