Preact is a front end web framework that’s similar to React.
It’s smaller and less complex than React.
In this article, we’ll look at how to get started with front end development with Preact.
Memoization
We can use the useMemo
hook to store results of expensive computations.
For example, we can write:
import { render } from "preact";
import { useMemo, useState } from "preact/hooks";
const expensive = (a, b) => {
//...
};
function App() {
const [a, setA] = useState(0);
const [b, setB] = useState(0);
const memoized = useMemo(() => expensive(a, b), [a, b]);
//...
return (
<div>
<p>{memoized}</p>
</div>
);
}
if (typeof window !== "undefined") {
render(<App />, document.getElementById("root"));
}
We have the expensive
function that does some expensive operation.
We call it in the useMemo
callback to cache its result.
memoized
is only computed again when a
or b
is changed.
We shouldn’t commit any side effects in useMemo
.
If we need to commit side effects, we should use useEffect
.
useCallback
The useCallback
hook lets us ensure that the returned function is referentially equal until the dependencies change.
For example, we can write:
import { render } from "preact";
import { useCallback, useState } from "preact/hooks";
function App() {
const [count, setCount] = useState(0);
const increment = () => setCount(count + 1);
const decrement = () => setCount((currentCount) => currentCount - 1);
const log = useCallback(() => console.log(count), [count]);
return (
<div>
<p>Count: {count}</p>
<button onClick={log}>log</button>
<button onClick={increment}>Increment</button>
<button onClick={decrement}>Decrement</button>
</div>
);
}
if (typeof window !== "undefined") {
render(<App />, document.getElementById("root"));
}
We pass in a callback into the useCallback
hook to cache the callback until the count
state changes.
This lets us prevent the callback from recreated every time the component renders.
useRef
The useRef
hook lets us get a reference to a DOM node in a function component.
For instance, we can write:
import { render, Fragment } from "preact";
import { useRef } from "preact/hooks";
function App() {
const input = useRef(null);
const onClick = () => input.current && input.current.focus();
return (
<>
<input ref={input} />
<button onClick={onClick}>Focus input</button>
</>
);
}
if (typeof window !== "undefined") {
render(<App />, document.getElementById("root"));
}
We call the useRef
hook to return a ref.
Then we assign it to the input with the ref
prop.
We also create the onClick
function to get the input element with the input.current
property and call focus
on it.
So when we click on Focus Input, the input will be focused.
useContext
The useContext
hook lets us access a context in a function component.
For example, we can write:
import { createContext, render, Fragment } from "preact";
import { useContext } from "preact/hooks";
const Theme = createContext("light");
function DisplayTheme() {
const theme = useContext(Theme);
return <p>Active theme: {theme}</p>;
}
function SomeComponent({ children }) {
return <>{children}</>;
}
export default function App() {
return (
<div>
<Theme.Provider value="dark">
<SomeComponent>
<DisplayTheme />
</SomeComponent>
</Theme.Provider>
</div>
);
}
if (typeof window !== "undefined") {
render(<App />, document.getElementById("root"));
}
We call createContext
to create the Theme
context.
Then we render the Theme.Provider
in app to set the value of the context.
And we can get the Theme
context value with the useContext
hook in the DisplayTheme
component.
We pass in the context that we want to access.
If our component is inside the Theme.Provider
then we can access its value.
Conclusion
We can use hooks to memorize data, cache callbacks, and share data between components with Preact.