Categories
Preact

Preact — Class Components and Fragments

Spread the love

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.

Class Components

We can add class components as we do with React.

For example, we can write:

import { Component, render } from "preact";

class Clock extends Component {
  constructor() {
    super();
    this.state = { time: Date.now() };
  }

  componentDidMount() {
    this.timer = setInterval(() => {
      this.setState({ time: Date.now() });
    }, 1000);
  }

  componentWillUnmount() {
    clearInterval(this.timer);
  }

  render() {
    const time = new Date(this.state.time).toLocaleTimeString();
    return <span>{time}</span>;
  }
}
if (typeof window !== "undefined") {
  render(<Clock />, document.getElementById("root"));
}

We create the Clock component by creating a class that extends the Component class.

Then in the constructor , we create the time state and set it to Date.now() as the initial value.

The componentDidMount hook lets us initialize the data.

In the method, we call setInterval to create the timer and in the callback, we call setState to set the state.

componentWillUnmount is called when we unmount the component, so we call clearInterval to clear the timer when the component unmounts.

In the render method, we render the current time.

Preact methods include lifecycle methods that are included in React class components.

They include:

  • componentDidMount() — after the component gets mounted to the DOM
  • componentWillUnmount() — prior to removal from the DOM
  • getDerivedStateFromProps(nextProps) — just before shouldComponentUpdate. Use with care.
  • shouldComponentUpdate(nextProps, nextState) — before render(). Return false to skip render
  • getSnapshotBeforeUpdate(prevProps, prevState) — called just before render(). The return value is passed to componentDidUpdate.
  • componentDidUpdate(prevProps, prevState, snapshot) — after render()

Fragments

We can use the Fragment component to render multiple components without a root element.

For example, we can write:

import { Fragment, render } from "preact";

function TodoItems() {
  return (
    <Fragment>
      <li>foo</li>
      <li>bar</li>
      <li>baz</li>
    </Fragment>
  );
}

const App = (
  <ul>
    <TodoItems />
    <li>qux</li>
  </ul>
);

if (typeof window !== "undefined") {
  render(App, document.getElementById("root"));
}

We have the TodoItems component, which renders a Fragment .

The resulting HTML only has the li elements.

In App , we combine TodoItems with li and render them together.

We can use <> and </> in place of <Fragment> and </Fragment> :

import { Fragment, render } from "preact";

function TodoItems() {
  return (
    <>
      <li>foo</li>
      <li>bar</li>
      <li>baz</li>
    </>
  );
}

const App = (
  <ul>
    <TodoItems />
    <li>qux</li>
  </ul>
);

if (typeof window !== "undefined") {
  render(App, document.getElementById("root"));
}

We can also return an array of components:

import { Fragment, render } from "preact";

function TodoItems() {
  return [<li>foo</li>, <li>bar</li>, <li>baz</li>];
}

const App = (
  <ul>
    <TodoItems />
    <li>qux</li>
  </ul>
);

if (typeof window !== "undefined") {
  render(App, document.getElementById("root"));
}

This is the same as what we have before.

If we use Fragment s in a loop, then we have to add the key prop and set it to a unique value so that the items can be distinguished:

import { Fragment, render } from "preact";

const items = [
  {
    id: 1,
    term: "apple",
    description: "red fruit"
  },
  {
    id: 2,
    term: "banana",
    description: "yellow fruit"
  }
];

function Glossary({ items }) {
  return (
    <dl>
      {items.map((item) => (
        <Fragment key={item.id}>
          <dt>{item.term}</dt>
          <dd>{item.description}</dd>
        </Fragment>
      ))}
    </dl>
  );
}

const App = (
  <div>
    <Glossary items={items} />
  </div>
);

if (typeof window !== "undefined") {
  render(App, document.getElementById("root"));
}

Conclusion

We can create class components and fragments as we do with React.

By John Au-Yeung

Web developer specializing in React, Vue, and front end development.

Leave a Reply

Your email address will not be published. Required fields are marked *