Security News
GitHub Removes Malicious Pull Requests Targeting Open Source Repositories
GitHub removed 27 malicious pull requests attempting to inject harmful code across multiple open source repositories, in another round of low-effort attacks.
Preact is a fast, 3kB alternative to React with the same modern API. It provides the thinnest possible Virtual DOM abstraction on top of the DOM. Its goal is to provide the same rich and robust ecosystem that React has, while being leaner and more efficient, often used for performance-critical applications and situations where bundle size is a factor.
Creating Components
This code sample demonstrates how to create a simple Preact component and render it to the DOM. It's similar to React but with a smaller footprint.
import { h, render, Component } from 'preact';
class MyComponent extends Component {
render() {
return <div>Hello, Preact!</div>;
}
}
render(<MyComponent />, document.body);
Using Hooks
This code sample shows how to use hooks in Preact, specifically the useState hook to create a simple counter component.
import { h, render, useState } from 'preact/hooks';
function Counter() {
const [count, setCount] = useState(0);
return (
<div>
<p>You clicked {count} times</p>
<button onClick={() => setCount(count + 1)}>
Click me
</button>
</div>
);
}
render(<Counter />, document.body);
Preact/Compat
This code sample illustrates how to use Preact/Compat to achieve React compatibility, allowing developers to use Preact as a drop-in replacement for React.
import React from 'preact/compat';
import ReactDOM from 'preact/compat';
function App() {
return <h1>Hello from Preact/Compat</h1>;
}
ReactDOM.render(<App />, document.getElementById('app'));
React is a declarative, efficient, and flexible JavaScript library for building user interfaces. It's larger in size compared to Preact but has a larger ecosystem and more built-in features.
Inferno is an extremely fast, React-like library for building high-performance user interfaces on both the client and server. It's similar to Preact in terms of performance goals but has its own set of APIs and optimizations.
Vue.js is a progressive framework for building user interfaces. Unlike Preact, Vue has a different API and embraces a different philosophy, focusing on declarative rendering and component composition with a more opinionated set of tools.
Svelte is a radical new approach to building user interfaces. Instead of doing the bulk of its work in the browser, Svelte shifts that work into a compile step that happens when you build your app. It's different from Preact in that it doesn't use a virtual DOM.
Name stolen, if found return to jason [at] developit [dot] ca
Preact is an attempt to recreate the core value proposition of React (or similar libraries like Mithril) using as little code as possible, with first-class support for ES2015. Currently the library is around 3kb (minified & gzipped).
It retains a large amount of compatibility with React, but only the ES6 Classes interface. As one would expect coming from React, Components are simple building blocks for composing a User Interface.
You don't have to use ES2015 to use Preact... but you should.
I'm going to assume you have some sort of ES2015 build set up using babel and/or webpack/browserify/gulp/grunt/etc. If you don't, start with preact-boilerplate.
The preact
module provides both named and default exports, so you can either import everything under a namespace of your choosing, or just what you need as locals:
import preact from 'preact';
// Tell Babel to transform JSX into preact.h() calls:
/** @jsx preact.h */
import { h, render, Component } from 'preact';
// Tell Babel to transform JSX into h() calls:
/** @jsx h */
Named imports work well for highly structured applications, whereas the default import is quick and never needs to be updated when using different parts of the library.
Instead of declaring the
@jsx
pragma in your code, it's best to configure it globally in a.babelrc
:{ "jsxPragma": "h" }
Out of the box, Preact provides an h()
function that turns your JSX into Virtual DOM elements (here's how). It also provides a render()
function that creates a DOM tree from that Virtual DOM.
To render some JSX, just import those two functions and use them like so:
import { h, render } from 'preact';
render((
<div id="foo">
<span>Hello, world!</span>
<button onClick={ e => alert("hi!"); }>Click Me</button>
</div>
), document.body);
This should seem pretty straightforward if you've used hyperscript or one of its many friends.
Rendering hyperscript with a virtual DOM is pointless, though. We want to render components and have them updated when data changes - that's where the power of virtual DOM diffing shines.
Preact exports a generic Component
class, which can be extended to build encapsulated, self-updating pieces of a User Interface. Components support all of the standard React lifecycle methods, like shouldComponentUpdate()
and componentWillReceiveProps()
. Providing specific implementations of these methods is the preferred mechanism for controlling when and how components update.
Components also have a render()
method, but unlike React this method is passed (props, state)
as arguments. This provides an ergonomic means to destructure props
and state
into local variables to be referenced from JSX.
Let's take a look at a very simple Clock
component, which shows the current time.
import { h, render, Component } from 'preact';
class Clock extends Component {
render() {
let time = new Date().toLocaleTimeString();
return <span>{ time }</span>;
}
}
// render an instance of Clock into <body>:
render(<Clock />, document.body);
That's great. Running this produces the following HTML DOM structure:
<span>10:28:57 PM</span>
In order to have the clock's time update every second, we need to know when <Clock>
gets mounted to the DOM. If you've used HTML5 Custom Elements, this is similar to the attachedCallback
and detachedCallback
lifecycle methods. Preact invokes the following lifecycle methods if they are defined for a Component:
Lifecycle method | When it gets called |
---|---|
componentWillMount | before the component gets mounted to the DOM |
componentDidMount | after the component gets mounted to the DOM |
componentWillUnmount | prior to removal from the DOM |
componentDidUnmount | after removal from the DOM |
componentWillReceiveProps | before new props get accepted |
shouldComponentUpdate | before render() . Return false to skip render |
componentWillUpdate | before render() |
componentDidUpdate | after render() |
So, we want to have a 1-second timer start once the Component gets added to the DOM, and stop if it is removed. We'll create the timer and store a reference to it in componentDidMount
, and stop the timer in componentWillUnmount
. On each timer tick, we'll update the component's state
object with a new time value. Doing this will automatically re-render the component.
import { h, render, Component } from 'preact';
class Clock extends Component {
constructor() {
super();
// set initial time:
this.state.time = Date.now();
}
componentDidMount() {
// update time every second
this.timer = setInterval(() => {
this.setState({ time: Date.now() });
}, 1000);
}
componentWillUnmount() {
// stop when not renderable
clearInterval(this.timer);
}
render(props, state) {
let time = new Date(state.time).toLocaleTimeString();
return <span>{ time }</span>;
}
}
// render an instance of Clock into <body>:
render(<Clock />, document.body);
Now we have a ticking clock!
The concept (and nomenclature) for props
and state
is the same as in React. props
are passed to a component by defining attributes in JSX, state
is internal state. Changing either triggers a re-render, though by default Preact re-renders Components asynchronously for state
changes and synchronously for props
changes. You can tell Preact to render prop
changes asynchronously by setting options.syncComponentUpdates
to false
.
Here is a somewhat verbose Preact <Link>
component:
class Link extends Component {
render(props, state) {
return <a href={ props.href }>{ props.children }</a>;
}
}
Since this is ES6/ES2015, we can further simplify:
class Link extends Component {
render({ href, children }) {
return <a {...{ href, children }} />;
}
}
// or, for wide-open props support:
class Link extends Component {
render(props) {
return <a {...props} />;
}
}
It is likely that some projects based on Preact would wish to extend Component with great new functionality.
Perhaps automatic connection to stores for a Flux-like architecture, or mixed-in context bindings to make it feel more like React.createClass()
. Just use ES2015 inheritance:
class BoundComponent extends Component {
constructor(props) {
super(props);
this.bind();
}
bind() {
this.binds = {};
for (let i in this) {
this.binds[i] = this[i].bind(this);
}
}
}
// example usage
class Link extends BoundComponent {
click() {
open(this.href);
}
render() {
let { click } = this.binds;
return <span onclick={ click }>{ children }</span>;
}
}
The possibilities are pretty endless here. You could even add support for rudimentary mixins:
class MixedComponent extends Component {
constructor() {
super();
(this.mixins || []).forEach( m => Object.assign(this, m) );
}
}
MIT
FAQs
Fast 3kb React-compatible Virtual DOM library.
We found that preact demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 9 open source maintainers collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
GitHub removed 27 malicious pull requests attempting to inject harmful code across multiple open source repositories, in another round of low-effort attacks.
Security News
RubyGems.org has added a new "maintainer" role that allows for publishing new versions of gems. This new permission type is aimed at improving security for gem owners and the service overall.
Security News
Node.js will be enforcing stricter semver-major PR policies a month before major releases to enhance stability and ensure reliable release candidates.