NewYour coding agent can read the release notes before it upgrades.Set up the MCP server →
npm · #1799 most downloaded on npm
Fast 4kb React-compatible Virtual DOM library.
Last release 5 days ago
30 Sep 2026
Ships fairly regularly
a new release about every 2 weeks
Nearly every release is documented
notes for 60 of the last 60 stable releases
Nothing withdrawn
no release was ever pulled
11 years old
287 releases · first in 2015
This has been a long time in the making for various virtual-dom based frameworks. Historically JSX was always transpiled to createElement function cal
This has been a long time in the making for various virtual-dom based frameworks. Historically JSX was always transpiled to createElement function calls.
// input
<div>foobar</div>
// output, we need to move "foobar" to `props.children`
createElement("div, {}, "foobar");
While this has served us well and is very reliable, it has proven to be hard to optimize. Most of the things we do in our createElement function could by done by babel directly, thereby making it smaller and faster. This is very desirable for us as this function is called a lot in any application. It's part of the so-called hot-path.
And that's exactly what the new signature does. It removes the need for us to pull out key from props, add back children to props and just makes the implementation simpler. As a nice benefit users won't need to manually import h/createElement anymore :tada:
// input
<li key="foo">foobar</li>
// output
jsx("li", { children: "foobar" }, "foo");
Usage with babel:
// babel.config.js
module.exports = {
plugins: [
["@babel/plugin-transform-react-jsx", {
runtime: "automatic", // defaults to classic (classic == createElement calls)
importSource: "preact", // NOT preact/jsx-runtime
}]
]
}
Note that the JSX transformer in TypeScript is a work in progress and will likely be released as part of version 4.1. We're currently running into https://github.com/microsoft/TypeScript/issues/40502 though, so the JSX typings are not found.
jsx-runtime support (#2764, thanks @JoviDeCroock, @marvinhagemeister)0 (#2757, thanks @marvinhagemeister)contenteditable (#2701, thanks @sventschui)style (#2723, thanks @JoviDeCroock)_suspended (#2765, thanks @marvinhagemeister)One column per quarter.
Fix deprecation warnings flooding console with preact/debug (#2711, thanks @marvinhagemeister)
tl;dr: A good handful of bug fixes make this release the ideal candidate to upgrade! Should be very safe to upgrade
Thanks to all the people who made this release possible! This is for everyone who took part in our discussions, helped report issues, did code contributions or just spread the word. Thank you all for another amazing release :raised_hands:
readonly in update fn (#2717, thanks @marvinhagemeister)preact/debug (#2711, thanks @marvinhagemeister)undefined instead of null in preact/compat (#2695, thanks @aralroca)react-relay (#2692, thanks @marvinhagemeister)href on nullish value (#2693, thanks @marvinhagemeister)undefined as default value for useRef (#2689, thanks @marvinhagemeister)preact/debug: Add component stack to prop type validation error, do not pass ref to prop-types validation (fixes mui incompatbility) (#2685, thanks @sventschui)dom lib (#2713, thanks @Gerrit0)useDebugValue typings to align with React (#2699, thanks @leader22)useErrorBoundary compat types (#2631, thanks @38elements)IntrinsicElements in ComponentProps (#2680, thanks @remcohaszing)CONTRIBUTING.md (#2702, thanks @marvinhagemeister)_tl;dr: This is a bug-fix only release and safe to upgrade _
tl;dr: This is a bug-fix only release and safe to upgrade :tada:
This release contains some amazing fixes by first time contributors! Thank you so much for everyone who filed issues or contributed PRs :heart:
download attribute handling (#2674, thanks @marvinhagemeister)diffElementNodes (#2658, thanks @perseveringman)useRef to null (#2648, thanks @JoviDeCroock)setState in constructor (#2640, thanks @sventschui)useRef to optional (#2651, thanks @38elements)capture definition. (#2643, thanks @JonathanBristow)preact/compat types (#2628, thanks @jeremy-coleman)package.json "authors" field (#2635, thanks @developit)_tl;dr: This is a bug-fix only release and safe to upgrade _
tl;dr: This is a bug-fix only release and safe to upgrade :tada:
We've landed some very anticipated fixes and therefore thought to cut a new release not soon after :raised_hands:
children if they're null in suspense (#2570, thanks @sventschui)textarea doesn't reset state (#2615, thanks @JoviDeCroock)null to forwardRef (#2600, thanks @JoviDeCroock)strokeMiterlimit accept a number as well (#2620, thanks @lfamorim)feDropShadow definition (#2609, thanks @Somnid)LICENSE files and fix submodule names (#2611, thanks @hbroer)CONTRIBUTING.md (#2603, thanks @futantan)This is a bugfix-only release and updating is seamless. We encourage everyone to do so :+1:
This is a bugfix-only release and updating is seamless. We encourage everyone to do so :+1:
Suspense from inadvertently modifying shared Component class (#2594, thanks @andrewiggins)Fragment edge case (#2551, thanks @JoviDeCroock)requestAnimationFrame while cancelling effects it (#2573, thanks @Hydrophobefireman)setState in render (#2565, thanks @jamesb3ll)forwardRef passing object instead of null (#2567, thanks @marvinhagemeister)compat (#2558, thanks @btk5h)useReducer from mutating the previous returned result (#2550, thanks @JoviDeCroock)This is a hotfix for today's 10.4.2 release that:
This is a hotfix for today's 10.4.2 release that:
Nothing published for this version
What a month we had! The weather is getting warmer and I think we can all enjoy a new refreshment in the form of a Preact release! The past weeks saw
What a month we had! The weather is getting warmer and I think we can all enjoy a new refreshment in the form of a Preact release! The past weeks saw a good chunk of bug fixes and a bit of house keeping. Upgrades should be as straightforward as swapping out the version number in package.json and running npm install or yarn install once!
It was one of those miracle days where all the pieces fell into place just perfectly: @JoviDeCroock got a HMR (=hot module reloading) prototype up without any changes to Preact and running in a couple hours! With the biggset achievement being that it works amazingly well in keeping hooks state around.
Since then he was contacted by various maintainers of bundlers to collaborate on an ideal developer experience. Today, about a little more than a week later we have them ready to be tested. And we need your feedback to make it the best HMR experience we can! Please file any issue you come across!
Oh and while we were at it @sventschui added a Preact template for snowpack! You can get it up and running via this line:
npx create-snowpack-app my-project --template @snowpack/app-template-preact
Recently deno cut it's 1.0.0 release which is a huge achievement. It's a new spin on what node could look like if it would have started fresh in 2019 and we're excited where this experiment will lead to! Despite it being very early it made some waves in our community and we were filled with joy when we noticed that the website is built with our beloved framework!
React.StrictMode to compat (#2529, thanks @developit)useReducer (#2526, thanks @hadeeb)IS_NON_DIMENSIONAL for compatibility with animation-iteration-count (#2523, thanks @viko16)debug (#2514, thanks @JoviDeCroock)hydrate export in compat (#2511, thanks @hadeeb)useEffect (#2493, thanks @JoviDeCroock)StrictMode to compat/src/index.d.ts (#2530, thanks @38elements)loading attribute to HTMLAttributes TypeScript interface (#2521, thanks @gerardo-rodriguez)CONTRIBUTING.md indentation (#2528, thanks @Vincent-Carrier)spy helper (#2524, thanks @JoviDeCroock)Fragments (#2507, thanks @andrewiggins)processingException check (#2483, thanks @JoviDeCroock)excessDomChildren creation (#2491, thanks @andrewiggins)js-framework-benchmark (#2489, thanks @andrewiggins)_tl;dr: This release allows our devtools extension to inspect hooks. Apart from that it includes the usual round of bug fixes._
tl;dr: This release allows our devtools extension to inspect hooks. Apart from that it includes the usual round of bug fixes.
We have a nice little present for you and that is hooks are now fully supported in Preact Devtools 0.5.0 :tada: The extension is currently awaiting approval in browsers stores and your browser will automatically update to it in the following days.
Both @andrewiggins and @JoviDeCroock went full on bug hunting mode and got some neat fixes in! We also saw an awesome contribution from @davidje13 who found an error in our types for memo :+1:
But the true star from the show is without a doubt that we finally have updated our typings to bring back the marquee element. @developit himself took the honors and made sure that developers can continue to use this element in their demo applications.
setProperty to set "value" and "checked" properties (#2472, thanks @andrewiggins)cloneElement (#2469, thanks @JoviDeCroock)displayName (#2454, thanks @marvinhagemeister)<marquee> typings (#2466, thanks @developit)defaultProps when wrapping components with memo (#2461, thanks @davidje13)_tl;dr: This release contains some very amazing improvements to hydration and to performance when memoized vnodes are used. We recommend everyone to u
tl;dr: This release contains some very amazing improvements to hydration and to performance when memoized vnodes are used. We recommend everyone to upgrade :tada:
We understand that the past weeks have been very strange for everybody across the world. We've spent that last weeks mainly focusing on making sure our families and loved ones are safe and taken care of. Whether you're using Preact at work or in a sideproject we hope that this release brings you a little bit of joy and makes your day a little bit brighter :stars:
vnodes bail out of renderWhen an vnode is equal to the one from the last render we will successfully bail out of rendering. This is a performance optimization many state libraries frequently make use of. The most well known of those is probably react-redux. We've wanted to add this for the initial Preact X release but had to postpone due to not having found the proper solution back then. In the following months we've passed around various ideas on how to best solve this and it wasn't until last month when it finally clicked and the pieces fell together. @JoviDeCroock had a prototype up running in a few days and has spent a lot of time into making sure that this performance optimization works in all scenarios. We can't stress enough how much of an accomplishment this is. This is really amazing work by @JoviDeCroock and we're over the moon that it has finally landed in Preact :tada:
When doing SSR there are cases where the DOM tree and the vnodes don't match. This can lead to a lot of problems, but for now we handle situations a bit more gracefully when there is no existing DOM node present. If we encounter that, we just opt out of hydration for that tree and revert back to doing a full diff. In the future we plan to add more warnings to preact/debug for that.
vnodes (#2386, thanks @JoviDeCroock)hydration (#2438, thanks @JoviDeCroock)setProperty for known bypass cases (key, children) (#2213, thanks @developit)act callback (#2433, thanks @robertknight)ref is mutable even if a DOM node is inserted into it (#2422, thanks @JoviDeCroock)defaultValue (#2420, thanks @JoviDeCroock)act type signature (#2444, thanks @ddayguerrero)_patchedLifecycles to compat/src/internal.d.ts (#2408, thanks @38elements)typeof (#2409, thanks @polemius)This is a maintenance release, upgrading should be free, please do report it in case you encounter any issues.
This is a maintenance release, upgrading should be free, please do report it in case you encounter any issues.
Preact batches all rendering work and executes from the top of the Virtual DOM tree to the bottom. However, if new rendering tasks were added during an existing render, they were processed without regard for their depth in the tree.
Thanks to a clever fix from @jviide, Preact's render queue is now immutable. Any new tasks added during rendering are placed into a second batch.
A peculiar issue users were seeing with material-ui related to a ref never getting populated, we went very deep into the codebase and found out that our forwardRef was a bit too eager, at creation it would already start forwarding. We moved this to a later point, now just before the vnode will get diffed the ref will be forwarded.
_tl;dr: Some minor changes which make this release safe to upgrade for everyone!_
tl;dr: Some minor changes which make this release safe to upgrade for everyone!
Another week, another Preact release! It seems like the previous one wasn't too long ago, but there are already so many cool changes in master that we're eager to bundle them in a neat release!
One insanely cool and very important change was done by @andrewiggins, who woke up one day and found a very elegant solution to handling conditionally rendered elements. Most virtual-dom-based frameworks mark a falsy result with some sort placeholder (sometimes referred to as "holes"), so that the diffing algorithm can ensure that elements are not moved around needlessly.
It's not just for performance though as they are some real world consequences to moving nodes around. The most common annoyance is <input>-elements losing focus whenever a parent is moved. With this change we are pretty confident that we squashed all known issues on that front :+1:
SVG also received a big change by @steveharrison . It's his first contribution Preact and he already knocked it out of the park with an excellent PR. HE went through the whole SVG spec and noticed that we didn't match some of the weird casings of SVG-Attributes properly and his PR remedies that beautifully! :100:
@pksjce finished her YouTube series where she reads through a portion of the Preact source code. With that she helped us tremendously in spotting areas in code which lacked comments and finally pushed us to create a proper "Contributing" guide. If you are considering contributing to Preact, this short document is well worth a read as it contains an overview of the repo's structure and answers for the most common questions regarding our code. That said if you feel like something is missing or you do have troubles understanding some sections of the source, please reach out to us! We're here to help and feedback about friction points is crucial to making Preact better for everyone :+1:
Checking our official website you may have noticed some slight changes here and there. They're mostly to simplify navigation or to give our docs a more fitting structure. The long term plan is to integrate our learnings about the most common support questions we get and fill in those spots. @NJalal7 spotted a few of those areas and even found a bug in Preact in the process that we we're promptly able to fix :raised_hands:
Thank you so much to everyone who contributed code, helped us in narrowing down issues or participated in making Preact even better. Preact wouldn't be were it is now without you all :heart:
isPropagationStopped fn to event (#2378, thanks @reznord)isDefaultPrevented fn to event (#2377, thanks @teodragovic)preact/debug (#2362, thanks @developit)event.isPropagationStopped() (#2380, thanks @38elements)setState inside componentWillMount (#2367, thanks @marvinhagemeister)useEffect/useLayoutEffect (#2358, thanks @JoviDeCroock)null placeholder DOM placement (#2355, thanks @andrewiggins)options.event type definition (#2381, thanks @38elements)excessDomChildren into the same code block (#2356, thanks @andrewiggins)null placeholders (#2352, thanks @andrewiggins)_tl;dr: Another bug-fix only release. It's safe to upgrade and we encourage everybody to do so_ :+1:
tl;dr: Another bug-fix only release. It's safe to upgrade and we encourage everybody to do so :+1:
It's sunny today and I haven't been outside yet, so I'll make it quick: Those pesky ref TypeScript errors when used with a CSS-in-JS library should be no more! So if you're using styled-components, emotion, goober or any other CSS-in-JS library, this update is for you! :100:
@robertknight found that false values where not special cased for aria-* attributes as they have a different way of treating boolean values compared to the DOM. Many boolean-like attributes like aria-checked have three states:
true element is checkedfalse element is unchecked, but it's possible to check itundefined (default) element can't be checkedAs usual thank you so much for everyone who helped make Preact better by contributing code or reporting issues! You all rock :+1:
false value in aria-attributes (#2347, thanks @marvinhagemeister)React.Children.map and .forEach (#2326, thanks @mhmdanas)React.Children.map/forEach missing index (#2322, thanks @JoviDeCroock)useErrorBoundary type with componentDidCatch (#2332, thanks @intrnl)ref typing with ReactElement (& popular react libraries) (#2099, thanks @xiel)useErrorBoundary's callback param optional (#2320, thanks @intrnl)useImperativeHandle tests (#2346, thanks @marvinhagemeister)ISSUE_TEMPLATE.md (#2342, thanks @JoviDeCroock)package.json to package.exports (#2319, thanks @MylesBorins)_tl;dr: Just a minor bug-fix-only release. Safe to upgrade for everyone._
tl;dr: Just a minor bug-fix-only release. Safe to upgrade for everyone.
We've been notified of an issue with the way we used the new exports feature that was introduced with Node 13, so we wanted to get out patch release as quickly as possible. Despite that we managed to include several other fixes in such a short timeframe that are worthy to mention.
This is big for us. @andrewiggins did an amazing PR which modifies our testing infrastructure to execute the tests against the minfied production bundles that are published to npm. This greatly reduces any chances of us not catching bugs that may exist in transpilers or the custom minify config we're using. And Andre promptly found a few misconfigurations already. Most of you propably didn't run into these issues as they are somewhat in the edge case area, but it's amazing to have a tool to automatically check our code for an mishaps :100:
In the early days of the Preact X rewrite we made a promise to ourselves in that we would check the effects on size for each PR. We started by printing out all the sizes of our exports via microbundle, but we did still have to compare those manually against what's in master. Both @kristoferbaxter and @developit have been joining forces and created a bot which does that automatically. As soon as the pipeline on a PR succeeds it will add a comment listing all the size differences :+1:
className not being applied when set to an empty string with preact/compat (#2309, thanks @JoviDeCroock)umd and make browser a modular export for future bundlers (#2311, thanks @JoviDeCroock)_tl;dr: This release contains a good number of bug fixes and we encourage all users to upgrade._
tl;dr: This release contains a good number of bug fixes and we encourage all users to upgrade.
A little bit of time has passed since our last release and we're excited to ship another one, making Preact even more robust! The fixes nearly touch all packages and further improves compatibility with third-party libraries :tada:
If you glance at the contributor names, you'll notice a few new ones there. It's safe to say that we were amazed and super ecstatic by the amount of new first time contributors to Preact! :raised_hands:
built-in elements (#2266, thanks @defx)preact/devtools import (#2246, thanks @marvinhagemeister)shouldComponentUpdate (#2125, thanks @andrewiggins)dom.nextSibling (#2294, thanks @andrewiggins)Children.map not flattening result (#2287, thanks @marvinhagemeister)size to an invalid value (#2285, thanks @marvinhagemeister)clipPathUnits (#2251, thanks @friebe)class and className being enumerable (#2280, thanks @marvinhagemeister)className patch not applied to props (#2279, thanks @marvinhagemeister)replaceNode calls (#2274, thanks @JoviDeCroock)shouldComponentUpdate getting called on setState after forceUpdate (#2258, thanks @laino)process.env.NODE_ENV check from preact/debug which broke browsers (#2257, thanks @marvinhagemeister)null as an initial value for useRef (#2281, thanks @armujahid)_lastDomChildSibling to _nextDom (#2297, thanks @andrewiggins)mangle.json with Suspense prop rename (#2298, thanks @andrewiggins)size action (#2270, thanks @developit)postinstall from running on installation (#2271, thanks @JoviDeCroock)createElement (#2273, thanks @zubhav)npm ci to speed up travis (#2255, thanks @JoviDeCroock)package-lock.json (#2254, thanks @JoviDeCroock)This release corrects an issue regarding hydration that was found in yesterdays 10.2.0 release :tada:
This release corrects an issue regarding hydration that was found in yesterdays 10.2.0 release :tada:
hydrate() (#2238, thanks @JoviDeCroock)Happy belated New Years to everybody :tada: We hope you enjoyed the holidays and had some time off to recharge :+1: Our very first release in 2020 bri
Happy belated New Years to everybody :tada: We hope you enjoyed the holidays and had some time off to recharge :+1: Our very first release in 2020 brings two new features and the usual round of bug fixes :100:
useErrorBoundary hookThere is a new hook called useErrorBoundary which allows you to catch errors that are thrown by any child components. It's essentially the hook version of componentDidCatch.
// 1. parameter is null or the error that was caught
// 2. paremeter can be called to reset the state
const [err, reset] = useErrorBoundary();
// Optional: You can pass a callback function that will
// be executed when an error occurs:
const [err] = useErrorBoundary(() => callMeMaybe());
Usage example:
// Example component that will throw an error on render
const SomeComponent = () => {
throw new Error("fail");
};
const App = props => {
const [err] = useErrorBoundary();
if (err) {
return <p>Something went wrong...</p>;
} else {
return <SomeComponent />;
}
};
This PR was one of the smallest ones, but something that makes working with different kind of lazy loaded modules a lot easier. Previously lazy would always use the default export of the imported module. With this change it's now possible to use it with any export.
// Look ma, no default export
const LazyFoo = lazy(() => import("./Foo").then(m => m.MyComponent));
On top of that we have the usual round of bug fixes. We'd like to thank everyone who reported them and helped us make Preact even better. Thank you so much!! :+1:
useErrorBoundary hook (#2205, thanks @JoviDeCroock)lazy() usage with non-default imports (#2212, thanks @developit)ref value on sibling vnodes (#2217, thanks @JoviDeCroock)Text nodes being re-rendered unnecessarily (#2215, thanks @developit)renderToString dependency error (#2207, thanks @developit)getDerivedStateFromError and componentDidCatch (#2200, thanks @JoviDeCroock)onReset/onFormData to Form Event types (#2209, thanks @thesmartwon)Suspense (#2229, thanks @sventschui)sinon global (#2220, thanks @JoviDeCroock)_tl;dr: A tiny maintenance release, which helps with debugging Preact apps._
tl;dr: A tiny maintenance release, which helps with debugging Preact apps.
This release is a lot smaller compared to our usual ones, but we deemed one feature important enough to have in users hands that we made this release. And that's component stacks which we hope will reduce the issue count in our tracker slightly :tada:
On top of that we want to congratulate @jamesb3ll for his first-time contribution to Preact :1st_place_medal: He found an issue and filled it with every detail one can imagine (codesandbox is awesome!). But instead of stopping there, he tinkered a bit and found a genius fix for it! Thank you for your PR :+1: :four_leaf_clover:
Whenever you include preact/debug you get a lot of hints and warnings about how you can make your application better. But sometimes it was hard to tell where the error originated from. To resolve that we automatically append a component stack trace telling you directly which component threw the error.
class Foo extends Component {
constructor(props) {
super(props);
// Doesn't do anything, `this.state = { foo: true }`
// should be used instead.
this.setState({ foo: true });
}
render() {
return <div>foo</div>;
}
}
function Bar() {
return <Foo />;
}
function Baz() {
return <Bar />;
}
The above code will print the following warning to the browser's console:
With the stack appended at the bottom it's much easier to track down the source :100: To get those beautiful file and line mappings, make sure that you have @babel/plugin-transform-react-jsx-source enabled in your babel config :+1:
componentWillReceiveProps not called on child component when parent is queued in the same commit (#2186, thanks @jamesb3ll)sinon esm bundle (#2188, thanks @marvinhagemeister)This way we are not affected by any breaking changes on React's side and have the possibility to extend the devtools with custom UI, like for the Comp…
tl;dr: This release adds support for the highly anticipated preact-devtools extension. It's in an early preview state, but it has proven to be very useful already for inspecting a component tree in our internal testing. Apart from that there is a new SuspenseList component to control loading in lists and the usual round of bug fixes.
Christmas comes early in the form of another feature packed Preact release :tada: We're particular proud of this one as it represents the results of a lot of work behind the scenes. Especially when it comes to the devtools.
For the longest time we've been able to reuse the react devtools extension that was (as the name implies) written specifically for React. We did this by hooking ourselves into the init procedure and shimming in a conversion layer that translated our inner workings to something React would use under the hood. Over the past year we've kept up with all the internal changes of React's private structures, but it took us more and more time to make sure that the integration wasn't breaking or running into weird edge cases.
Faced with a choice we decided to pursue the development of our own extension specifically written for Preact. This way we are not affected by any breaking changes on React's side and have the possibility to extend the devtools with custom UI, like for the Composition-API PR #1923 .
That said the extension is not what we would call final yet. It's more of an early preview, akin to an alpha release. Despite bugs you may encounter, we found it useful enough in our testing that we didn't want to hold back any longer.
Download it here: https://preactjs.github.io/preact-devtools/
SuspenseList is a new component that can control the order in which any child suspensions are revealed. Take a list of images for example. Due to the browser firing the requests to download them in parallel, the images may appear in any order. This can be a bit jarring, when some sort of appear animation is involved. With SuspenseList we can force all images to appear at the same time, inorder or in reverse.
In the following example A will appear first, followed by B even if C was loaded before B. And finally C will appear.
// `revealOrder` can be one of 'forwards', 'backwards' or 'together'
<SuspenseList revealOrder="forwards">
<Suspense fallback={<span>Loading...</span>}>
<A />
</Suspense>
<Suspense fallback={<span>Loading...</span>}>
<B />
</Suspense>
<Suspense fallback={<span>Loading...</span>}>
<C />
</Suspense>
</SuspenseList>
SuspenseList optimisations (#2121, thanks @jviide)SuspenseList component (#2063, thanks @prateekbh)Suspense should support unmounting suspender (#2134, thanks @sventschui)this type for event handlers (#2166, thanks @marvinhagemeister)type attribute (#2147, thanks @Rafi993)touch events in compat (#2120, thanks @sventschui)Fragment (#2107, thanks @jviide)onToggle event to TypeScript defs. (#2151, thanks @xorgy)FunctionComponent from preact/compat (#2087, thanks @jokester)dir property values (#2108, thanks @antonk52)createElement (#2135, thanks @developit)useMemo _callback to _factory (+0 B) (#2131, thanks @andrewiggins)if clause in suspense _catchError (#2119, thanks @sventschui)VNode compat options (-62 B) (#2116, thanks @andrewiggins)master (#2158, thanks @andrewiggins)compat src and tests (#2124, thanks @andrewiggins)_tl;dr: This release is a bug fix only release and all users are encouraged to update._
tl;dr: This release is a bug fix only release and all users are encouraged to update.
This week saw many cool improvements surrounding our TypeScript definitions. Thanks to an amazing contribution from @lukeshiru the event target is now correctly inferred for all native elements. This alone should remove many manually casted event arguments in your code :tada:
Together @JoviDeCroock and @cristianbote set their minds on fixing a few newly reported issues surrounding refs and the like. Personally, I'm pretty impressed how quickly they could identify and resolve the issues. Much respect to you two :+1:
As the year is coming to an end @andrewiggins did some house-cleaning and found various places where we could save even more bytes! I don't know how he does it and it's just amazing to witness so much pure talent!
Beside that, the changes mainly revolve around maintenance tasks. We've switched to prettier for automatic code formatting, lowering the barrier for new contributors even more. The formatting is automatically applied on each commit via a git-hook, and everything will be taken care of for you :100:
We also saw two exciting contributions from Googlers: @jridgewell found a very hard to spot unnecessary case in a regex we use to append px to certain CSS values and @jakearchibald found an html attribute we missed in our typings :tada:
Like in our past release we'd like to take a moment to thank everybody who contributed, not just code but also made the time to write bug reports. Thank you so much :+1:
refs correctly (#2055, thanks @JoviDeCroock)renderCallbacks are called when sCU bails out (#2081, thanks @JoviDeCroock)ref for forwardRef (#2075) (#2076, thanks @cristianbote)hook scheduling logic (-17 B) (#2085, thanks @andrewiggins)IS_NON_DIMENSIONAL (#2046, thanks @jridgewell)currentTarget on event handlers for IntrinsicElements (#2084, thanks @lukeshiru)ref typings for IntrinsicElements (#2070, thanks @lukeshiru)as html attribute to TypeScript defs (#2068, thanks @jakearchibald)funding field to package.json (#2096, thanks @developit)createContext tests to no longer import internal data (#2090, thanks @andrewiggins)preact-charts from README (#2092, thanks @pmkroeker)README section about preact/devtools (#2091, thanks @peterswallow)__p to __ in mangle.json (#2044, thanks @38elements).json files use 2-space (#2078, thanks @developit)prettier (#2065, thanks @marvinhagemeister)This release fixes a build issue that caused errors when using effect hooks.
This release fixes a build issue that caused errors when using effect hooks.
_renderCallbacks mangle configuration (#2060, thanks @robertknight)This release corrects an issue where a debug warning was printed incorrectly to the console, that (rightfully) confused users. So we wanted to fix tha
This release corrects an issue where a debug warning was printed incorrectly to the console, that (rightfully) confused users. So we wanted to fix that as quick as possible :+1:
setState warning always being printed (#2057, thanks @marvinhagemeister)layoutEffects in component render callbacks array (+0 B) (#2050, thanks @andrewiggins)debug tests into multiple files and fix some bugs in debug (#2047, thanks @andrewiggins)_tl;dr: This is release contains mostly bug fixes and some size reductions. We encourage everyone to upgrade._
tl;dr: This is release contains mostly bug fixes and some size reductions. We encourage everyone to upgrade.
Just a week has passed since the last release and there are already an exciting number of new commits in master. Hackoktoberfest has had really positive effects on us and we're excited to see some new contributors in this release :100:
As you can see from the changelog: @andrewiggins is currently on a byte removing spree, so I thought it'd be appropriate to list them in their own category :tada: A few others joined him and marie kondo'ed everything that didn't spark joy in us!
Besides some great savings, there are new debug warnings for components and fixes for our Suspense implementation :tada:
setState or forceUpdate on an unmounted component (#2037, thanks @andrewiggins)<Suspense> (#2025, thanks @andrewiggins)ref not always called in useImperativeHandle (#2021, thanks @JoviDeCroock)coerceToVNode inside of toChildArray (-21 B) (#2040, thanks @andrewiggins)useImperativeHandle to use useLayoutEffect (-35 B) (#2003, thanks @andrewiggins)renderCallbacks as a general per-component commit queue (#2011, thanks @andrewiggins)nonce to JSX HTMLAttributes types for better Content Security Policy support. (#2035, thanks @calvinf)vnode typings (#2015, thanks @pmkroeker)compat/mangle.json (#2053, thanks @38elements)_afterPaintQueued and _fallback to mangle.json (#2043, thanks @38elements)preact/compat in readme (#2029, thanks @developit)_force and _lastDomChild to mangle.json (#2023, thanks @developit)_suspensions to mangle (#2019, thanks @JoviDeCroock)_tl;dr: This is a standard bug-fix release with no new features. We encourage everyone to upgrade_
tl;dr: This is a standard bug-fix release with no new features. We encourage everyone to upgrade
Wow, we've been overwhelmed with the reactions to our final Preact X release! We saw a huge uptick in npm downloads to 200.000 per week :tada: Another exciting announcement is that Google AMP is officially using Preact under the hood. We've receivied many more thank you notes (and even stroopwafels!) from companies using Preact. Those range from small companies to big enterprise ones, where Preact is used in a wide span of different environments.
We preactively allocated the weeks after the big launch for a period of bug-fixes only in case something slipped through. It was admittedly a more conservative decision after our long alpha and beta period, but we wanted to make sure that you all would have a butter smooth experience no matter what :stars: It's safe to say that it went really well and we've only received a couple bug reports so far :tada:
In the short amount of time that has passed since the release, we managed to squash a good portion of those! Thank you so much to everyone for reporting bugs and helping us track them down! You rock :+1: :100:
virtual-dom (#1987, thanks @JoviDeCroock)context values (for createContext-API) (#2005, thanks @JoviDeCroock)setState callbacks (-6 B) (#2010, thanks @andrewiggins)preact-context library (#2001, thanks @jackbravo)forceUpdate enqueued child update being skipped (#1988, thanks @marvinhagemeister)Portal node to container instead of prepend (#1971, thanks @toraora)_force flag from component (#1984, thanks @marvinhagemeister)replaceNode not always taking effect (#1970, thanks @JoviDeCroock)null from VNode.type TS definition and add some TS tests (#1994, thanks @andrewiggins)_force to internal.d.ts (#1990, thanks @38elements)VNode typings (#1979, thanks @andrewiggins)shouldComponentUpdate (#1980, thanks @JoviDeCroock)We originally planned to release a sort-of migration release as version 9 with just the breaking changes from X, but that got canned because many user…
tl;dr: Preact X is the next major version of Preact fully packed with features like Fragments, Hooks, componentDidCatch, Test-Utils, Debug-Warnings, many compatibility fixes and so much more :tada:
It's finally happening! After months of hard work we've crossed the finish line and are over the moon with excitement to finally mark Preact X as stable. We'd like to thank everybody who tested it and submitted bug reports.
We originally planned to release a sort-of migration release as version 9 with just the breaking changes from X, but that got canned because many users reported that the upgrade process was easy enough and didn't warrant a long migration period in-between. In fact we got many reports that the upgrade could be done in under an hour, despite some of the breaking changes in X, making the need for a migration release even less desirable.
Preact X ships with several major features and we combined them all in a single document on our site. If you're upgrading an existing Preact 8.x project, we got you covered with a detailed upgrade guide.
To give a quick summary of the new features:
FragmentscomponentDidCatchpreact/hooks addonpreact/test-utils addoncreateContext APIcompat moved to corepreact/debugAgain, we highly recommend checking out our new site and specifically the what's new section.
shouldComponentUpdate handling to take more edge cases into account (#1931, thanks @JoviDeCroock)UNSAFE_* lifecycles being overwritten in compat (#1946, thanks @marvinhagemeister)PureComponent rerendering when __source changes (#1950, thanks @JoviDeCroock)useState not applied in rare cases (#1948, thanks @JoviDeCroock).forceUpdate() to participate in the update queue (#1939, thanks @developit)vnode._children should keep their type as array when diffing (#1924, thanks @cristianbote)opacity) (#1927, thanks @JoviDeCroock)disableRemotePlayback to HTML Attributes (#1955, thanks @JoviDeCroock)volume to HTML Attributes (#1938, thanks @jessicabyrne)__source and __self (#1958, thanks @JoviDeCroock)So uhm... just yesterday we've published RC2 and we've mentioned that it would be likely the last RC before going final. Turns out that fate had other
So uhm... just yesterday we've published RC2 and we've mentioned that it would be likely the last RC before going final. Turns out that fate had other plans. One seemingly minor change to our jsx constructor function lead to pretty weird and nasty bug depending on whether the code was run in use strict mode or not. @jviide wrote up a great summary on how this issue came to be.
children refs in createElement (#1917, thanks @JoviDeCroock)_tl;dr: This release contains a lot of bug fixes in many areas and we encourage everyone to upgrade. We're confident that this is the last rc release
tl;dr: This release contains a lot of bug fixes in many areas and we encourage everyone to upgrade. We're confident that this is the last rc release before marking X as stable.
It's time for another Preact release :tada: We've spent the past weeks on make Preact as robust as we can. Most fixes are ones you all submitted to our tracker. This is super awesome and we wouldn't be where we are without all your help!
On top of countless fixes, a few minor features found their way into the
package like isValidElement that can be used to check if something is valid to
render, meaning it's a valid child that was created by h/createElement.
The test utils also received much love and we're very impressed with how quickly
@robertknight was able to land support for async callbacks and nested calls
to act :100: This is useful in cases where triggering an effect or state change
involves async steps, such as waiting for a fetch call to resolve.
We think it'd be good to give a setSate of the union here about where we are
with the devtools. As many of you are aware we've always depended on the
react-devtools extension for a long time now. We were very excited to
integrate with version 4, not just because of the new featureset, but also
because the adapter and protocol is so much better than before.
We got very far, but despite of all our efforts we ran into blocker issues with the expected order of events that need to be sent to the extension. Our internals differ quite a bit and after trying for weeks to get it right we ultimately went back to the drawing board.
It became clear that just writing our own extension would be less resource intensive and would make it easier for us to maintain. It's pre-alpha right now, but we expect to mature in the coming weeks/month. Here is a screenshot as a little sneak peek:
Very early pre-alpha preview of preact-devtools
We'll keep you posted! Here is the full list of changes in this release:
isValidElement to core (#1861, thanks @marvinhagemeister)children (#1858, thanks @marvinhagemeister)form attribute on buttons and inputs (#1863, thanks @sventschui)setState in a constructor (#1857, thanks @marvinhagemeister)act callbacks and nested calls to act (#1854, thanks @robertknight)setState calls with accurate this.state (#1748, thanks @JoviDeCroock)useImperativeHandle handles after rendering (#1909, thanks @JoviDeCroock)shouldComponentUpdate leading to invalid DOM without children (#1888, thanks @JoviDeCroock)shouldComponentUpdate check for context.Consumer (#1901, thanks @cristianbote)replaceNode argument not always replacing node (#1900, thanks @JoviDeCroock)shouldComponentUpdate (#1871, thanks @marvinhagemeister)undefined styles not being cleared (#1853, thanks @marvinhagemeister)act not flushing effects/updates if global effect/update queues are non-empty before act call (#1851, thanks @robertknight)refs to memo'ed components (#1860, thanks @sventschui)forwardRef & memo proxy components as React components (#1844, thanks @developit)select value (#1838, thanks @marvinhagemeister)fn.prototype where possible (#1835, thanks @developit)compat types (#1752, thanks @marvinhagemeister)key to all jsx elements (#1887, thanks @marvinhagemeister)getDerivedStateFromProps and getDerivedStateFromError (#1874, thanks @38elements)VNode.constructor to internal type definitions (#1810, thanks @38elements)form attribute test on IE11 (#1868, thanks @marvinhagemeister)_tl;dr: This release contains many little fixes and we encourage all X users to upgrade._
tl;dr: This release contains many little fixes and we encourage all X users to upgrade.
As we're nearing closer to the actual release we're hoping to sweeten the wait with another rc-release :tada: While the docs are coming along nicely we have a preview of our upcoming migration guide to Preact X from 8.x. We have a little polish left to do, but apart from that the new docs are basically ready :fingers_crossed:
But back to the actual release! This time the fixes touch a broad area in Preact. There are a few for Portals, some for onTransition* or onAnimation* events and the usual round of browser or typing PRs.
It's arguably less feature packed than previous releases, but that's a really good sign for the release candidate phase. It means that X is mature and is in great shape for going gold :+1: :100:
props when replacing a node and don't diff when hydrating (#1786, thanks @JoviDeCroock)lazy not forwarding refs (#1826, thanks @JoviDeCroock)hydration flag (#1802, thanks @developit)animation and transition events handlers not being recognized (#1804, thanks @JoviDeCroock)createPortal -> normal vnode (#1805, thanks @JoviDeCroock)Portal children always being mounted (#1781, thanks @marvinhagemeister)debug crash with hooks import (#1773, thanks @JoviDeCroock)Partial to setState (#1779, thanks @pmkroeker)xvfb config for Travis CI (#1822, thanks @prateekbh)_Note: This may be a breaking change if you are sending an incorrect DOM structure to the client and relied on hydrate to correct that for you. To fix…
tl;dr: This is mostly a bugfix only release, with one notable exception. Due to popular demand we reversed our decision to remove support for string styles and brought them back :four_leaf_clover: All users on the next tag are encouraged to upgrade :+1:
You may have already noticed the rc suffix in the release number and that is because we're finally out of beta :+1: rc stands for roughly complete... uh... release candidate and this means that a final Preact X release is really close :checkered_flag: We do wanted to give it another phase of testing before going final though and it gives us a bit time to get our docs in shape.
Don't worry if there is something you would have loved to see in X, but that didn't make the cut. The final X release is more of a sign that we think it's stable and maybe even more so than 8.x ever was :tada: This also means that we can focus more on adding new features and reduce our current maintenance overhead of working on two release lines simultaneously. The upgrade should be pretty seamless for everyone and we'll publish a complete migration guide along with the final X release. If you for some reason can't update to X don't worry. We'll keep maintaining the 8.x release line for a good while.
This release contains some noteworthy fixes to our Portal-Component. But not just that, we also added back support for string styles due to popular demand. Originally we removed them to save bytes, but it turns out that this feature is way to useful not to have. Additionally it aligns better with out philosophy with being "closest to the DOM". Thank you'all for everyone who participated in that journey and helped us make the right decision moving forward :+1: :100:
This change has been cooking for a while and plays well along with the research @developit and @housseindjirdeh have been doing about hydration. When you look at the way SSR works, you'll notice that pretty much the complete diff phase is redundant. The HTML that is sent to the client matches the vnode tree completely, so there isn't much point in comparing changes. The thing is that we can't remove it completely though, because we still need to attach event listeners. For that case we introduced a faster code path which bypasses most of the diffing. After the initial render is done, Preact will continue with the usual diff mode.
Note: This may be a breaking change if you are sending an incorrect DOM structure to the client and relied on hydrate to correct that for you. To fix this make sure to sent HTML that matches the initial vnode tree on the client.
At this point we'd like to give a shoutout to @robertknight who continues to quietly maintain enzyme-adapter-preact-pure. It's rock solid already and it's only getting better. Be sure to check it out :nerd_face:
Without further ado: Here is the full changelog of our first (p)release candidate :1st_place_medal:
requestAnimationFrame fallback when tab is not focused (#1763, thanks @calebeby).github dir (#1765, thanks @developit)eslintignore into package.json (#1764, thanks @developit)Portals (#1749, thanks @JoviDeCroock)props during hydration (#1697, thanks @developit)value (#1760, thanks @JoviDeCroock)catchRender with catchError (#1742, thanks @andrewiggins)replaceNode not unmounting when diffing twice with replaceNodea (#1723, thanks @JoviDeCroock)compat types and tests (#1740, thanks @andrewiggins)_childDidSuspend (#1735, thanks @pmkroeker)compat render not destroying existing DOM (#1729, thanks @marvinhagemeister)tl;dr _This is a bug-fix-only release and all users are encouraged to update. A final release is in sight _
tl;dr This is a bug-fix-only release and all users are encouraged to update. A final release is in sight :tada:
It's the summer and while hopefully most of you will be able to enjoy the time outside we couldn't pass the opportunity to let our latest beta release free into the world! This might be the last beta we'll publish before going gold, so stay tuned :wink: For this reason we focused purely on shaking all bugs out and make this the most stable preact release we can :+1: :100:
Most notably this includes some rethinking of how we deal with Fragments
internally. Over the past weeks we received bug reports which all seemed to be
related and it turns out they were! They all shared the problem that the sibling
order was different after a component update. We all got our heads together
and found a better internal implementation for Fragments that's a lot more
sound theoretically. It should fix all ordering issues for good :+1: :checkered_flag:
Although this release is quite and we've set our sights on a final release we're already working on getting the Preact debug adapter in shape for the upcoming react-devtools v4 :tada: It's not just more performant, but also adds the hooks panel right in the devtools. More on that soon :wink:
As always Preact wouldn't be what it is today without you all. Whether you've been helping us squash bugs, joined feature discussions or just spread the word, we're really thankful to be part of such an amazing community. We even got to meet some of you at this years JSConfEU!
With all said: We can't wait to unleash the final release soon! If you're new to the beta releases, don't worry. The final release will be accompanied with a migration guide :+1:
Because of the internal restructuring preact-render-to-string needs to be updated to at least version 5.0.4.
act (#1683, thanks @JoviDeCroock)diff instead of diffChildren and other golf ⛳ (#1715, thanks @andrewiggins)useRef with useState (#1679, thanks @JoviDeCroock)falsy event values beeing added (#1712, thanks @cristianbote)Portal unmounting and props diffing (#1691, thanks @JoviDeCroock)diff with next DOM sibling in forceUpdate (#1689, thanks @andrewiggins)ancestorComponent with vnode parent pointer (+5 B) (#1688, thanks @andrewiggins)__self and __source (#1690, thanks @mxstbr)_children & combine Fragment and Component diffing (-73 B) (#1658, thanks @andrewiggins)typeof check for h (#1676, thanks @JoviDeCroock)style to error on strings (#1675, thanks @pmkroeker)preact-charts to Component Libraries (#1667, thanks @pmkroeker)…handling hydration. Note that this is formally a breaking change, but it won't likely cause you any trouble. What's different is that existing server-…
tl;dr: We're excited to be one step closer to a final Preact X release! It's packed full with the addition of Suspense, lazy, performance improvements and the usual round of bug fixes :tada:
Internally we've been referring to this one as the "Hitchcock"-Release. @jviide came up again with the very fitting release title :+1: We're proud to welcome @sventschui as the newest addition to our team! And oh boy did he join us with a bang! :tada:
@sventschui went ahead and added basic support for both the Suspense component and lazy() to preact/compat. With these in place it is now a lot easier to do proper code-splitting. Just have a look at this example on how they can be used together:
import { Suspense, lazy } from "preact/compat";
const Other = lazy(() => import('./OtherComponent'));
function Foo() {
return <Suspense fallback={<div>Loading...</div>}>
<Other />
</Suspense>
}
In the snippet above the Other component will only be displayed once it's loaded. Until then the Suspense component allows the user to display any fallback content making it ideal for any sort of spinners for example :+1: :1st_place_medal:
This was one of the remaining road blocks in getting Next.js to work with Preact X :tada: Note that our implementation is still considered an experimental preview :clock1030:
Last cycle we had a lot of fun finding ways to make Preact even smaller! In fact, we had so much fun that we continued a bit to do so leading up to this release :100: These size optimizations are really important, because they allow us to offset the byte cost for new features while staying within our self imposed byte size limit :whale:
Following @developit and @housseindjirdeh's talk on Progressive Hydration at Google I/O'19, we've landed the first changes to support a more ideal way of handling hydration. Note that this is formally a breaking change, but it won't likely cause you any trouble. What's different is that existing server-rendered DOM element attributes will no longer be removed during hydration. This translates to a huge performance benefit for boot-up time, which means your page gets interactive and ready-to-go noticeably sooner if you are doing Server Side Rendering or prerendering :rocket:
We removed support for string styles in favor of setting style properties only with objects. This aligns our behavior with various other virtual-dom based libraries out there :heavy_check_mark: Note that this is a breaking change from 8.x and you may need to update your code:
// before
<div style="color: LightGoldenrodYellow;" />
// after
<div style={{ color: "LightGoldenrodYellow" }} />
This one was long on our list of possible ways to cut down on size. Nonetheless we are aware that this might be a controversial change. If you have a lot of string styles or want to continue using them, you can use preact-string-styles to patch this behavior back into Preact X. If you don't agree this change, please let us know!
Sometimes we need a bit inspiration on how to build complete Applications with Preact. We were super stoked to see that one of the demos at Google I/O uses our library and can be inspected here on GitHub. The demo is a minesweeper-like game called Proxx that makes clever use of some advanced web features like Web Workers and WASM. Be sure to check it out!
If any of you wonderful people happen to be at JSConfEU in Berlin this weekend, let's meet in person! Both @cristianbote and I (@marvinhagemeister) will be attending, and we have plenty of stickers with us :wink:
In closing we've been super thankful for every PR or bug report we received in the past cycle. They are crucial to make Preact rock solid and help us find edge cases we may not have thought of. Thank you all!
Suspense and lazy (#1593, #1638 thanks @sventschui)proxx demo (#1654, thanks @talentedandrew)bundlesize dependency (#1641, thanks @JoviDeCroock)travis-size-report to the CI (#1633, thanks @wardpeet)documentView since this introduced a regression (#1631, thanks @cristianbote)useEffect warning instead of throwing error (#1623, thanks @yuqianma)preact.js.gz size down by 53 B ⛳️ (#1599, thanks @jviide)VNode.props instead of VNode.text (#1600, thanks @jviide)null placeholder behavior (#1661, thanks @andrewiggins)props.key even when key === 0 or key === "" (#1607, thanks @jviide)replaceNode (#1647, thanks @JoviDeCroock)react-hot-loader compatibility by not checking on vnode ref (#1644, thanks @JoviDeCroock)this reference in componentWillUnmount under context Consumer (#1627, thanks @sventschui)dangerouslySetInnerHTML during hydration (#1595, thanks @developit)vnodes when oldVNode has no dom reference (#1617, thanks @JoviDeCroock)self is not available in non-browser environments (#1618, thanks @cristianbote).some should not be used for effect invoke/cleanup (#1613, thanks @JoviDeCroock)preact-render-to-string dependency (#1603, thanks @JoviDeCroock)compat (#1609, thanks @pmkroeker)tl;dr: This release contains important bug fixes to our reconciler and a security fix. We highly recommend to upgrade to this version if you are runni…
tl;dr: This release contains important bug fixes to our reconciler and a security fix. We highly recommend to upgrade to this version if you are running a past alpha or beta release of Preact X.
As mentioned in our past release notes we spent more time on making preact even smaller. It didn't take long until @andrewiggins found ways to cut down close to 40 bytes in just a few hours. We don't know how he does it, but the bytes are surely afraid of him by now! Amazed by that headstart @jviide soon followed with a PR of his own which removed another 30+ bytes. He's been helping us with loads of performance improvements in the past weeks and you may already know him from his outstanding contributions to htm, but this is his very first PR to Preact. Be sure to give him a high-five when you see him somewhere :tada:
The temptation was real and @JoviDeCroock tackled one of the bigger fish that was back on our minds for a while: Our focus workaround. Due to past bugs in our reconciler during the alpha phase we had to add a workaround so that a focused input wouldn't lose focus when sibling elements were moved or removed completely. The workaround took some toll on the final build size and jovi managed to finally crack the nut and made it possible to remove that workaround.
After just a few days we're happy to report that close to 100 bytes had to pack up their things and leave the repo :point_right: We're super happy with the result and have surpassed our initial approximations on possible savings :checkered_flag:
VNode hardening :muscle:One thing that's very important for us is making sure that we make it easy to
do the right thing by default regarding security. For that all modern frameworks
prevent the most common Cross-Site-Scripting Attacks (short: XSS). Frameworks
that are based on the virtual-dom are unique in that regard as most exploits
rely on some way to inject a malicious string through innerHTML.
Preact 8.x included a protection for the following scenario:
// Malicious JSON received from server or created
// from user input via JSON.parse() in app code
const evil = {
type: "div",
props: {
dangerouslySetInnerHTML: "<script>alert('xss')</script>"
}
};
function App() {
// Inject our evil vnode
return <div>My name is {evil}</div>;
}
render(<App />, document.body);
The exploit basically comes down to a possibility of a user being able
to inject any js object as a virtual-dom node (= vnode) and in effect
being able to call dom.innerHTML = evilString. Note that this
requires either a compromised or insecure server or an input field which
is parsed via JSON.parse() and put back into JSX unmodified to pull of
the exploit successfully. This is why we think it's a low priority security
issue.
We take any security issue seriously and have added a similar protection mechanism to Preact X :+1: Thanks goes to @JoviDeCroock and @wardpeet who did the inital prototype.
useDebugValue and useImperativeHandle :wave:These two hooks are lesser known than useState and the like, but are sometimes
used in third-party libraries. useDebugValue is especially important to
remain compatible with the upcoming mobx-react which relies a lot on hooks
internally. With these 2 hooks added we are now 100% compatible with the react
ecosystem on that front :tada:
As we all know server-side-rendering (short: ssr) is a neat way to improve
the time to first paint. This is especially important if you're working for
a newspaper or magazine where the bottom line is very dependent on performance.
First-Time contributor @LukasBombach championed an improved way to directly
replace a DOM node with a render() call. This is very useful on a site where
sections are rendered independently from each other.
It works by being able to pass a third replaceNode parameter to render.
We were not only impressed by the attention to detail in his PR, but also by
the incredible description and info-graphics around the changes. This was
beyond stunningly awesome :+1: Check out the description in his PR for more information.
As usual this release is packed with a bunch of fixes and minor performance
improvements. Most notably are correctness fixes and improvements to animation
event handling. On top of that we added an example page with styled-components
to test with. We knew some users had issues with it and Preact 8.x in the past
so we wanted to make sure that it will work right out of the box with Preact X.
And the good news is that we haven't found any issues so far :tada:
In general we fell like we're reaching a stage with Preact X where it is pretty stable and mature at this point. A final release is likely not too far off in the future :100: :wink:
But enough talk, here is the full list of changes:
focusElement (#1548, thanks @JoviDeCroock)replaceNode parameter to render() (#1557, thanks @LukasBombach)styled-components example (#1574, thanks @marvinhagemeister)useImperativeHandle (#1556, thanks @JoviDeCroock)useDebugValue hook (#1554, thanks @marvinhagemeister)_lastDomChild disregarding placeholders (#1587, thanks @marvinhagemeister)_dirty call neglect this (#1584, thanks @JoviDeCroock)_tl;dr: This release contains several important improvements to our reconciler (the part that is responsible for moving the DOM nodes around). Because
tl;dr: This release contains several important improvements to our reconciler (the part that is responsible for moving the DOM nodes around). Because of that we highly recommended everyone who is on one of the previous alpha releases to upgrade.
Easter is coming up, and we have enough changes in master to warrant a release :tada: During the past weeks we managed to resolve lots of bugs. Not just your standard bugs, but loads of the trickier ones :+1: For the first time in a long while we are below the 100 issue mark :tada: With release we feel confident that it can be used in a wider target audience. Our featureset is complete, and we even added a lot more than was initially planned for Preact X. If you're missing something where you feel like that it must absolutely be added in the initial release and can't wait for the next minor one, please voice your opinion in our issue tracker.
Fragments considered stableThe most notable change is a very welcomed refactoring of our reconciler to fix known issues we had with Fragments. @andrewiggins spent a lot of time the last weeks on getting this one right. What's most impressive about this is that he didn't just fix one or two of the issues surrounding Fragments, and instead blew us all away by squashing all of them in one go.
In classic Andre fashion the PR is very thorough with detailed annotations about the changes in each commit. He just has that incredible talent for stepping back and assessing the situation with fresh eyes.
Demo inspired by https://codepen.io/JavaScriptJunkie/pen/pPRooV
One cool optimization that our new code base allowed us to do is introducing the concept of placeholders (often referred to as "holes") in our renderer. These placeholders allow us to skip a bit of work when updating conditionally rendered elements like in the following example:
<div>
{condition && <Foo />}
<h1>Faster🎉⚡</h1>
{!condition && <Bar />}
<p>vroooooom 🚀</p>
</div>
Seeing that this is quite a common pattern in Preact-based apps, we are very excited about the performance improvements of that technique. Another positive side effect is that it opened up the chance to land further enhancements to keyed and unkeyed children!
Once thing that was bugging us, is that even with version X, Preact would do more work than necessary when nested updates are involved. This happened when a child component enqueued an update via setState and later one of the parent components does the same thing, we'd render the child component twice (Child -> Parent -> Child). This happened because we would process the queue in the order the updates where added. We can effectively remove a whole render by making our processing depth-aware. Our new code detects that we can optimize the ordering by rendering the parent first which will automatically update the child component.
This work was initially started by @JoviDeCroock and later joined by the whole team. We're quite happy with the result and noticed the enhanced rendering speed in our own apps :100:
For a while now @robertknight has devoted his time to greatly enhance our testing story. He wrote an adapter for the popular enzyme testing library from Airbnb. It even works with both Preact 8.x and Preact X. We've been using it quite a bit in our own projects and wanted to mark it as an official package.
At some point in the future we're planning to move all the other libs over to the organization, too. But there is no concrete timeline available for now. The main benefit for us the org provides is a shared permission model for contributions so that we don't have to bug @developit each time we make a PR to our offspring libraries like preact-router and preact-render-to-string.
With this release we have surpassed the total bundle size of the 8.x line. Due to improved tree shaking the hello world example will be smaller though. Depending on how the future will unfold we may put more focus in the next weeks on finding ways to cut down on size :crossed_fingers: This is a lot easier to do with an extensive test suite like we have now :+1: Stay tuned!
Without further ado, here is the full changelog:
diffChildren calls (#1515, thanks @andrewiggins)act should be able to track and flush the full queue and all subsequent queues (#1520, thanks @JoviDeCroock)on (#1530, thanks @JoviDeCroock)prop-types dependency (#1525, thanks @natevw)_depth to mangle.json (#1542, thanks @38elements)warn about deprecated properties (#1511, thanks @JoviDeCroock)
A bit quicker than usual, but we felt like the recent changes are worthy enough to be part of a dedicated release. Originally we planned to just include a fix for our prop-types validation in debug and when looking at our open PRs we couldn't resist to add those that were already done.
The awesome release name is brought to you by @jviide :sunglasses:
When setState/forceUpdate was called in a lifecycle other than componentDidUpdate we sometimes didn't clean up the previous DOM correctly. This lead to ghosting effects and was the last fix needed to get our new people demo fully working (it uses mobx and mobx-state-tree). We're happy to see this is resolved :+1:
One of the PRs we are really excited about was made by @just-boris: He moved our JSX types under a dedicated preact namespaces allowing our types and @types/react to coexists without any conflicts. This is big for anyone using TS and we can't thank him enough for his PR :tada:
useEffect 🔢We reworked our cleanup code for effects with this release. Before new effects are executed we cleanup all previous ones instead of cleaning and executing them one-by-one. This was confusing and the new behavior is much more obvious when writing effectful code.
As with our last releases we received numerous amazing reproductions and issues which allowed us to quickly spot a bug and fix it. We really appreciate the short feedback loop. Without it we wouldn't be able to improve Preact X as much as we can :+1:
_dom being null whenever sCU returns false (#1484, thanks @marvinhagemeister)undefined and null (#1505, thanks @JoviDeCroock)It's time for another Preact X release :tada: The past weeks were very productive and we're very happy to have been able to improve Preact on many fro
It's time for another Preact X release :tada: The past weeks were very productive and we're very happy to have been able to improve Preact on many fronts.
mjs is no more :100: ✅We are very happy to have removed our .mjs bundles and are back with standard .js files. This was a common error when trying out the alpha with webpack because the resolution for mjs files is different. We're very thankful for @lukeed who stepped up and created a workaround with a custom webpack plugin that we have been referring to. But we all knew that we wanted to correct that with our next release and make Preact work out of the box with webpack again. This release does just that and you can safely remove webpack-modules :+1:
For this release we spent a few days working on improving the developer experience when writing Preact apps. For that we added more warnings to preact/debug which should catch some common issues you may have run into. These will be visible in your browsers console :tada:
createElement/hfunctionrender() doesn't exist in the DOMuseEffect/useLayoutEffectHere is an example:
Thanks to the stunningly beautiful "people demo" that @phaux contributed we were able to catch two issues when using Preact together with mobx-react. Our compat shim is now on a level where mobx-preact isn't needed anymore (it was lagging behind in terms of features compared to mobx-react).
We brought in the first batches of reconciler fixes but have a few pending changes left to do. These mainly include fixes that will make Fragment support rock solid and an enhancements to createContext. When these are stable we'll move forward to a beta release :+1: We even have some cool performance improvements in the pipeline 🤫
As always we'd like to take time to thank everyone who has filed issues or participated in discussion. The issues in particular are much higher quality than just a few months ago. We've received quite a few comments on twitter or in person from friends working on other OSS projects that they love our community and the positivity ours is known for. Just wanted to pass on the praise to you all :tada: :heart:
Without further ado, here is the full change set:
useEffect/useLayoutEffect dependencies (#1495, thanks @JoviDeCroock)useMemo/useCallback when dependencies haven't been specified (#1499, thanks @JoviDeCroock)createElement warnings in debug (#1494, thanks @marvinhagemeister)render() (#1487, thanks @JoviDeCroock)unstable_batchedUpdates and replace mobx-preact with mobx-react in demo app (#1477, thanks @marvinhagemeister)*.mjs -> *.module.js (#1425, thanks @marvinhagemeister)teardown to test-utils (#1458, thanks @JoviDeCroock)event.persist should be a function, not an object (#1498, thanks @JoviDeCroock)componentWillUnmount (#1471, thanks @marvinhagemeister)setState callback or enqueue a render in constructor (#1454, thanks @JoviDeCroock)_dom is null (#1452, thanks @Almo7aya)vnode (#1450, thanks @JoviDeCroock)_nextState (#1446, thanks @mochiya98)_prevState (#1442, thanks @mochiya98)test-utils export in preact/compat (#1436, thanks @JoviDeCroock)Object.assign with custom assign function (#1433, thanks @marvinhagemeister)px suffix for CSS Custom Properties (#1426, thanks @marvinhagemeister)componentDidUpdate arguments (#1455, thanks @38elements)tagName prop trying to change element type (#1419, thanks @JoviDeCroock)act (#1437, thanks @JoviDeCroock)vnode type definition (#1447, thanks @38elements)The weekend is coming and we thought it be a good time to make another alpha release for everyone to play with 🎉
The weekend is coming and we thought it be a good time to make another alpha release for everyone to play with 🎉
This was a wonderful week for us. More and more bug reports contain links to a reproducible test case. You all are simply amazing! We wouldn't be able to fix this many bugs without all your help 👍 Even our contributions had an alltime high with excellent PRs from the community!
Despite fixing many bugs we landed a new package to help you test hooks in Preact 🎉
preact/test-utilsWith hooks having their own scheduling logic, we didn't have a good testing story up until now! First-time contributor @JoviDeCroock went right into it and quickly had a prototype running. With the blink of an eye he had a PR that was ready to be merged. These testing utilities are inspired by the excellent react-dom/test-utils tools and share a similar act() function :+1:
For testing hooks effectively we need to flush pending effects synchronously. The brand new act() function allows you to do just that:
import { act } from "preact/test-utils";
let spy = sinon.spy();
function StateContainer() {
useEffect(spy);
return <div />;
}
// Wrap the render() with `act` to flush hooks automatically
act(() => render(<StateContainer />, document.body));
// Do your assertions 🎉
expect(spy).to.be.calledOnce;
If you're working with class-based components you can use the new setupRerender function to flush pending state updates in your tests:
import { setupRerender, Component } from "preact/test-utils";
// Setup rerender logic first
const rerender = setupRerender();
let updateState;
class App extends Component {
constructor() {
super();
this.state = { count: 0 };
updateState = () => this.setState(prev => ({ count: ++prev.count }));
}
render() {
return <div>count: {this.state.count]}</div>;
}
}
// Render your component
render(<App />, dom);
expect(dom.textContent).to.equal("count: 0");
// Trigger a state update
updateState();
// Flush all state updates
rerender();
expect(dom.textContent).to.equal("count: 1");
It's his first contribution to Preact and we couldn't be more ecstatic about his work. Give him a round of applause 👍 It's also good to know for us that our code remains very accessible for new contributors.
style properties not working (#1375, thanks @mochiya98)Portal rendering undefined tags into the DOM (#1367, thanks @marvinhagemeister)this.props not set for PureComponent components (#1384, thanks @marvinhagemeister)console.error for caught errors in the devtools adapter (#1385, thanks @yuqianma)setState is called in componentWillReceiveProps (#1369, thanks @mochiya98)foreignObject not being treated as svg (#1391, thanks @marvinhagemeister)onBeforeInput not attaching event handler (#1366, thanks @marvinhagemeister)React.isValidElement check failing for vnodes created with Preact (#1380, thanks @marvinhagemeister)<select>.value not working (#1397, thanks @JoviDeCroock)<select> only selecting last item (#1405, thanks @JoviDeCroock)force flag blocking state update in second render() (#1377, thanks @developit)Element.prototype.remove (#1395, thanks @marvinhagemeister)forwardRef and memo ignoring refs when composed together (#1358, thanks @marvinhagemeister)_prevState for devtools out of core (#1379, thanks @developit)oldChildrenLength to save bytes (#1386, thanks @yuqianma)setProperty for style strings (#1394, thanks @choumx)static methods (#1365, thanks @marvinhagemeister)mangle.json files (#1378, thanks @developit)componentWillReceiveProps (#1387, thanks @developit)Phew what an exciting few days it has been! We've been blown away by the wonderful responses to our 10.0.0-alpha.0 release and are excited to ship the
Phew what an exciting few days it has been! We've been blown away by the wonderful responses to our 10.0.0-alpha.0 release and are excited to ship the next one with a good dozen of bug fixes.
In just three days we received a lot of awesome PRs pushing Preact X forward 👍 This wouldn't be possible with the outstanding issues we've received. They all had a link to a codesandbox where the issue could be easily reproduced. This is every maintainer's dream and we can't stress enough how much time it saves us to fix bugs 🚀
MessageChannel to setTimeout + requestAnimationFrame 🎉 (#1346, thanks @cristianbote)componentWillReceiveProps in relation to shouldComponentUpdate 💯(#1348, thanks @mochiya98)memo() 🎉 (#1347, thanks again @mochiya98)server.js in npm package (#1332, thanks @developit)this binding in setState callback (#1344, thanks @marvinhagemeister)props and state reference when shouldComponentUpdate returns false (#1351, thanks @marvinhagemeister)Text nodes out of toChildArray (#1357, thanks @developit)_parentDOM (#1320, thanks @andrewiggins)hgroup to TypeScript typings (#1340, thanks @ForsakenHarmony)isReactComponent-property in preact/compat (#1337, thanks @marvinhagemeister)Up until now it has lived in a separate repository making it harder to introduce breaking changes.
tl;dr: Preact X is the next major release which comes with a plethora of highly requested features like Fragments, componentDidCatch, createContext, hooks and many compatibility improvements with third-party libraries.
Fragments has been the most requested feature for Preact for a long time and we were very keen on bringing them into Preact! With Preact X they are now finally here 🎉 Use the new Fragment export in your components to render children elements inline with their parent, without an extra wrapping DOM element. For example:
import { render, Fragment } from "preact";
function Table() {
return (
<table>
<tr>
<Columns />
</tr>
</table>
);
}
function Columns() {
return (
<Fragment>
<td>Hello</td>
<td>World</td>
</Fragment>
);
}
render(<Table />, document.body);
// Resulting DOM:
<table>
<tr>
<td>Hello</td>
<td>World</td>
</tr>
</table>
You can also return arrays from your components:
function Columns() {
return [
<td>Hello</td>
<td>World</td>
];
}
Don't forget to add keys to Fragments if you create them in a loop:
function Glossary(props) {
return (
<dl>
{props.items.map(item => (
// Without the `key`, Preact can't efficiently add,
// remove, remove new elements as the list changes
<Fragment key={item.id}>
<dt>{item.term}</dt>
<dd>{item.description}</dd>
</Fragment>
))}
</dl>
);
}
Fragments are a major new feature of Preact X that largely motivated the rewrite
from Preact 8. We could really use a lot of help testing and validating our
Fragment implementation. If you find something that doesn't seem right, we would
really appreciate reporting a minimally reproducible example to help us improve
our implementation and messaging around Fragments.
We all wish errors wouldn't exists in Web-Apps but sometimes they do happen. With componentDidCatch all errors that happen inside render or another lifecycle method can be caught. This can be used to display user-friendly error messages, or write a log entry to an external service in case something goes wrong.
class Foo extends Component {
state = { error: false };
componentDidCatch(err) {
logErrorToBackend(err);
this.setState({ error: true });
}
render() {
// If an error happens somewhere down the tree
// we display a nice error message.
if (this.state.error) {
return <div class="error">Something went wrong...</div>;
}
return <Bar />;
}
}
Because setting a fallback content in an error case is so common we made this even nicer by adding for getDerivedStateFromError which calls setState automatically under the hood.
class Foo extends Component {
state = { error: false };
static getDerivedStateFromError(err) {
// return argument for setState
return { error: true }
}
render() {
// If an error happens somewhere down the tree
// we display a nice error message.
if (this.state.error) {
return <div class="error">Whoops! This should not have happened</div>;
}
return <Bar />;
}
}
Preact now supports Hooks. React has some phenomenal documentation on hooks that's worth a read, particularly if you're getting started with them for the first time. In Preact, you import hooks from preact/hooks. If you're using a recent version of most bundlers, any hook functions you don't use won't be included in your application.
Here's what hooks look like in Preact:
import { h, render } from 'preact';
import { useState } from 'preact/hooks';
function Counter() {
const [count, setCount] = useState(0);
// ^ default state value
return (
<div class="counter">
Current count: {count}
<button onClick={() => setCount(count + 1}}> +1 </button>
<button onClick={() => setCount(count - 1}}> -1 </button>
</div>
);
}
render(<Counter />, document.body);
The createContext-API is a true successor for getChildContext(). Whereas getChildContext is fine when you're absolutely sure to never change a value, it falls apart as soon as a component in-between the provider and consumer blocks an update via shouldComponentUpdate when it returns false. With the new context API this problem is now a thing of the past. It is a true pub/sub solution to deliver updates deep down the tree.
import { createContext } from "preact";
const Theme = createContext("red");
function Button() {
return <Theme.Consumer>
{value => <button style={{ color: value }}>click</button>}
</Theme.Consumer>;
}
function App() {
return <Theme.Provider value="blue">
<Button />
</Theme.Provider>;
}
Sometimes it's the little things that make a huge difference. With the recent advancements in CSS you can leverage variables for styling:
function Foo(props) {
return <div style={{ "--theme-color": "blue" }}>{props.children}</div>;
}
To be able to support all the recent advancements in the excellent react-devtools extension we knew we had to redo our devtools adapter. In previous version we disguised Preact as React v15 to connect to them but this was getting more and more difficult with features added in later releases like the Profiler tab.
For Preact X we rewrote our adapter from scratch and can directly hook into our own renderer. This is a lot more straightforward for us and eases feature development greatly. It didn't take long for us to bring the Profiler into Preact 👍
<img width="969" alt="screenshot 2019-03-05 at 01 12 05" src="https://user-images.githubusercontent.com/1062408/53771660-c5e30a80-3ee3-11e9-8204-547b14330874.png">
Although we were always keen on adding new features and pushing Preact
forward, the preact-compat package didn't receive as much love. Up until now
it has lived in a separate repository making it harder to introduce breaking
changes.
// Preact 8.x
import React from "preact-compat";
// Preact X
import React from "preact/compat";
forwardRefUNSTABLE_*-Lifecycle hooksmemoTo make maintenance easier we dropped all legacy APIs that were available
in React versions prior to v16. This includes the DOM-Factories API,
createClass, string refs and a few more.
We were very careful to introduce as few breaking changes as possible. As a user
the most noticable change will be that props.children is not guaranteed to be
an array anymore. This change was necessary to be able to support rendering
components that return an array of children without wrapping them in a
root node. On top of that this fixes quite a few issues with third-party
components that expect props.children to be undefined when no children are
passed around.
VNode shape has changedWe renamed/moved the following properties:
attributes -> propsnodeName -> typechildren -> props.childrenThe children of a VNode are no longer guaranteed to be a flat array.
props.children could be undefined or it could be a nested array of children.
Pass props.children to the newly exported helper toChildArray to always get
an array back.
import { h, toChildArray } from "preact";
function MyComponent(props) {
// Always convert props.children to an array
const children = toChildArray(props.children);
return <div>I have {children.length} child nodes</div>;
}
Note: toChildArray will flatten and remove non-renderables like null, undefined, true, and false from the children array.
setState no longer modifies state synchronouslyIn Preact X the state of a component will no longer be mutated synchronously.
This means that reading from this.state right after a setState call will
return the previous values. Instead you should use a callback function to
modify state that depends on the previous values.
this.state = { counter: 0 };
// Preact 8.x
this.setState({ counter: this.state.counter++ });
// Preact X
this.setState(prevState => {
// Alternatively return `null` here to abort the state update
return { counter: prevState.counter++ };
});
render() has changedThe root render function (the one you import from preact) has changed. It no
longer returns the newly created DOM element. Its return type is now void. We
made it simpler, by removing the third argument that was used to hydrate the
DOM. Use the hydrate function instead to hydrate a server rendered DOM tree.
When render is called multiple times on the same elements, the trees will be
merged together. It no longer just appends to the DOM. This change will be
very welcomed by new users as it was a frequeuent source confusion 🎉
import { render, hydrate } from "preact";
const root = document.getElementById("root");
// Render into the DOM
render(<div>foo</div>, root);
// calling `render` a second time will merge the trees like you would expect it to
render(<div>foo<span>bar</span></div>, root);
// Or use `hydrate` if you're making use of server side rendering
hydrate(<div>foo</div>, root);
preact/devtools is part of preact/debugOur devtools adapter has been moved into our debug package and doesn't require a dedicated import statement anymore. The preact/debug package must be imported before preact to prevent our devtools integration to be overwritten by the default one supplied by the react-devtools extension.
A lot has changed in the past years in the bundling space. Most bundlers now
offer excellent support for tree-shaking, where unused exports can be dropped
if they are not used. In the past we always exported an additional object as
the default export. But because of the nature of JavaScript it is very hard
to prove that an object property will never be used, they were never removed.
By removing the default export completely, only the code you need will
be included in the bunlde. The rest will be tree-shaken away.
// Preact 8.x
import preact from "preact";
// Preact X
import * as preact from "preact";
// Preferred: Named exports (works in 8.x and Preact X)
import { h, Component } from "preact";
Note: This change doesn't affect preact/compat. It still has both named and a default export to remain compatible with react.
spellcheck) the values false and '' have different
meaning so being able to render false is importantComponent constructor no longer initializes state to an empty object. If
state has not been previously set, it will be set to an empty object the first
time the component is rendered, after the constructor has been calledsetState will not enqueue an update. This change was made to support returning null from the updater function, which allows users to abort an update. If you just want to trigger an update and don't care about the state itself you can call it with an empty object setState({}).rerender export has been removed.render(null, container) no longer renders an empty text node but instead renders nothingoptions.debounceRendering. The value of options.debounceRendering must asynchronously invoke the passed in callback. It is important that contributors to Preact can consistently reason about what calls to setState, etc. do, and when their effects will be applied. See the links below for some
further reading on designing asynchronous APIs.
Fragments lead to more DOM operations than necessarydevtools panelChange Preact v8 "browser" field to "umd:main" (#1963, thanks @andrewiggins)
This release is a maintenance release and all users of the 8.x release line are encouraged to upgrade to it.
This release is a maintenance release and all users of the 8.x release line are encouraged to upgrade to it.
This is a maintenance release and fixes a minor issue with the packaging of the devtools import. All users on the 8.x release line are encouraged to u
This is a maintenance release and fixes a minor issue with the packaging of the devtools import. All users on the 8.x release line are encouraged to upgrade.
This is a maintenance release for Preact's 8.x versions. We'd like folks to try out Preact X, but if you're still using 8 we have you covered.
This is a maintenance release for Preact's 8.x versions. We'd like folks to try out Preact X, but if you're still using 8 we have you covered.
This release includes support for createRef(), and updated TypeScript definitions.
Fix a bug in 8.4 where nested preact.render() calls would cause an infinite loop when flushing the mount queue. (#1269, thanks @pl12133!)
8.4 where nested preact.render() calls would cause an infinite loop when flushing the mount queue. (#1269, thanks @pl12133!)Nothing published for this version
The cat is out of the bag 🙌 We finally revealed on what we have in store for the next major version of preact which will be called Preact X 🎉 To give
The cat is out of the bag 🙌 We finally revealed on what we have in store for the next major version of preact which will be called Preact X 🎉 To give you a sneak peak of what will be included check out this talk over at this.javascript video, slides. It's hard to make an estimate right now on when it will be released, but rest assured we are nearly done and are working on upgrading the ecosystem (cli, router,...) to ensure a smooth release.
That said we very excited about recent community contributions. This release contains some awesome performance enhancements brought to you by @lowaa and @rpetrich. On top of that there are some minor bug fixes and a lots of improvements to our typings.
Thank you so much for everyone involved 👍
ref invocation (#1235, thanks @developit)cloneElement test (#982, thanks @decadef20)componentDidUpdate tests (#1198, thanks @andrewiggins)onInvalid form event (#1221, thanks @namankheterpal)h() overloads (#1246, #1214, thanks @gpoit, @garybernhardt)AnyCompoent type (#1249, thanks @scurker)key (#1248, thanks @wojtczal)boolean as a component child (#1219, thanks @KasparEtter)onError image event (#1209, thanks @jackmoore)defaultProps (#1181, thanks @Alexendoo)cloneElement definition (#1197, thanks @hiddedejong)flow@0.82 (#1230, thanks @ngyikp)options flow type (#1204, thanks @reyronald)babel@7 (#1212, thanks @38elements)Fixes an issue in 8.3.0 where prevState (as passed to componentDidUpdate) pointed to the wrong interim state value when batching (#1186, thanks @carlh
8.3.0 where prevState (as passed to componentDidUpdate) pointed to the wrong interim state value when batching (#1186, thanks @carlhopf!)🙌 We've added support for the new getDerivedStateFromProps() and getSnapshotBeforeUpdate() lifecycle hooks. (#1094 & #1112). A huge thank-you to @andr
🙌 We've added support for the new getDerivedStateFromProps() and getSnapshotBeforeUpdate() lifecycle hooks. (#1094 & #1112). A huge thank-you to @andrewiggins and @marvinhagemeister for their amazing work on this!
.mjs now! (#1165, thanks @mathiasbynens for the nudge)setState() could mutate state in-place (#1170, thanks @Mitranim for the fix and @dandv for digging into the Apollo issue!)spellcheck={false} is now set as an attribute (#1110, thanks @marvinhagemeister!)Note: Preact will continue to support these browsers (that is to say, continue to avoid relying on features they don't support), but recent updates to Mocha mean our tests don't run there. Special thanks to @mkxml, @andrewiggins, @k1r0s and @marvinhagemeister for working to improve the test suite in this release!
on*Capture event handler attributes and PointerEvents to the TS definitions (#1101 #1102, thanks @jakearchibald)controlsList attribute for media elements (#1134, thanks @wayou)This release fixes an issue with our minification pipeline, which incorrectly mangled export declarations.
This release fixes an issue with our minification pipeline, which incorrectly mangled export declarations.
ref and key attribute #1051, thanks @andrewigginsVNode #1082, thanks @andrewigginsWe're happy to cut a new release and are excited about the much improved TypeScript defintions.
We're happy to cut a new release and are excited about the much improved TypeScript defintions.
We love how much the community around preact has grown in the past months (18k stars!) and we'd like to thank everyone who was involved. Wether you've helped finding bugs, made code contributions or improved our documentation, this release wouldn't be possible without you. :tada:
Changes:
preact-router #988, thanks @developitFix preact/debug failing to load in Webpack 3 + ES Modules (#924 #935, thanks @whitetrefoil)
preact/debug failing to load in Webpack 3 + ES Modules (#924 #935, thanks @whitetrefoil)[debug]: Warn when passing incorrect arguments to render() (#885, thanks @markselby9)
render() (#885, thanks @markselby9)AnyComponent (#905, thanks @mike-north)HTMLAttributes type definition (#907, thanks @niedzielski)A more durable fix for the Babel preset recursion issue (thanks @rmacklin)
This release makes some tweaks to the newly released preact/debug.
This release makes some tweaks to the newly released preact/debug.
preact/debug- Fix missing donation message 🙈
8.2.2 fixes a bunch of little issues encountered by those upgrading to 8.2.1 👍
8.2.2 fixes a bunch of little issues encountered by those upgrading to 8.2.1 👍
src for ES Modules compatibility (#792, thanks @slaskis)npm is unavailable (#804, thanks @andrejsm)preact/debug: Support for attributes with no .toString() (#754, thanks @plusCubed)preact/debug: Allow string refs when preact-compat is present (#807)preact/debug: Fix error when preact-compat was not presentBugfix: revert flushMounts() change to fix incorrect timing
flushMounts() change to fix incorrect timing (#750)We're now shipping an ES Modules build and are using Babel 6! (thanks @btd, @matthewp, @gpoitch)
preact/debug by @NekR: import it and get lovely warnings, errors & devtools integration!Promise#then) for async! (#708)<undefined> (#671, @dharFr)As of 8.1.0, we're officially out of beta! If you were waiting to upgrade to Preact 8, now's the time.
As of 8.1.0, we're officially out of beta! If you were waiting to upgrade to Preact 8, now's the time.
💁 8.x included a few important backwards-incompatible changes, so we've put together a 8.0 migration guide to help. The guide includes "polyfills" you can use to restore 7.x functionality so your migration goes smoothly.
If you have any issues upgrading, including anything caused by this release, drop us a line!
This release resolves a few issues people have had when upgrading.
componentDidMount on children before componentDidUpdate on parent (#440, #506 - thanks @robertknight!)preact/debug will be released shortly and does a much better job reporting stack traces!🌈 Also worth noting, the linkstate module is now available.
fixes an issue with preact-router (thanks @lukeed & @kbaxter!)
Quick follow-up to 8.0.0
preact-router (thanks @lukeed & @kbaxter!)This release represents a huge step forward for Preact:
This release represents a huge step forward for Preact:
key for PFC's, class integrations, capturing events.💁 If you're looking to upgrade, be sure to read the quick guide.
key now works perfectly on PFC's. It also means you could use state and lifecycle methods in Functional Components... (#163, #517, #536, #586, #474)linkState() has been removed from Preact itself. It is being published as a standalone linkstate module shortly.class and className no longer serialize Object values to Strings. Instead, use classnames (#401)preact/aliases is no longer necessary. createElement() is now an alias of h() right out of the box!<undefined> (#574)Symbol. Instead of try to use Symbol.for('preactattr'), __preactattr_ is always used.setTimeout(0) instead of Promises. It's smaller, doesn't swallow rendering errors in Safari, and was already the fallback (#357)componentDidUnmount() lifecycle method is removed. Use componentWillUnmount().onXxxxCapture is now supported for registering capturing event handlers.focus and blur are no longer automatically capturing by default.ref functions attached to DOM nodes are no longer invoked for updates, only for mount/unmount.key prop now triggers a remount (#338)Text or Array constructors for type checks, instead relying on duck typing (#595, #530)Here's the list of changes itemized by commit: https://github.com/developit/preact/compare/master...8
Your coding agent can read these notes before it upgrades. Set up the MCP server →