Preact
https://github.com/preactjs/preact
Features
- Switch back to microticks for scheduling as the default (#3911, thanks @marvinhagemeister , @JoviDeCroock)
Bug Fixes
- Fix hydrating
<textarea>
with value prop (#3891, thanks @andrewiggins) - Prevent memory leak when creating and destroying root nodes by clearing
currentComponent
(#3908, thanks @JoviDeCroock) - Fix regression in
10.12.1
from #3889 which could lead to a state not updating after a context update was enqueued (#3906, thanks @JoviDeCroock) - Fix tests assertions for IE11 (#3912, thanks @marvinhagemeister)
Types
- Add
indeterminate
property (#3837, thanks @rschristian) - Add aria role attribute values (#3904, thanks @shoonia)
- Add missing SVG Elements to types (#3905, thanks @shoonia)
- Add Missing
MemoExoticComponent
type inpreact/compat
(#3898, thanks @rschristian) - Add ARIA attribute types (#3910, thanks @andrewiggins)
Bug Fixes
- Fix non-numeric numbers passed to
width
orheight
attribute not working correctly (#3888, thanks @JoviDeCroock) - Fix
createContext
update being blocked byshouldComponentUpdate
(#3889, thanks @marvinhagemeister)
Features
- Use microtick outside of events (#3879, thanks @JoviDeCroock)
- Re-sort rerender queue if modified while we are processing rerenders (#3871, thanks @andrewiggins)
- Preserve event handler return values (#3812, thanks @developit)
Bug Fixes
- Fix: avoid bailing in strict equality (#3884, thanks @JoviDeCroock)
- When unmounting, continue with the last DOM element's nextSibling (#3878, thanks @andrewiggins)
- Fix parameters or JSX dev runtime (#3880, thanks @wooorm)
- Improve Fragment unmounting while correctly swapping nested fragments (#3875, thanks @andrewiggins)
- Clear css properties when passed undefined (#3862, thanks @andrewiggins)
- Debug: limit "object as children" error to elements (#3801, thanks @developit)
- Invoke setState callbacks setup in componentWillMount (#3806, thanks @andrewiggins)
Typings
- add exactOptionalPropertyTypes support to html attributes (#3868, thanks @deadem)
- Changes
EventHandler<...>
to have athis
of typevoid
. (#3867, thanks @MicahZoltu) - Narrows type of
parent
in render functions. (#3863, thanks @MicahZoltu)
Maintenance
- Improve suspense test spies (#3856, thanks @andrewiggins)
- docs: Fix a few typos (#3844, thanks @timgates42)
- docs: Removes recommendation for
preact-cli
(#3816, thanks @rschristian)
Bug Fixes
- Add an explicit
default
export for compatibility with esbuild (#3783, thanks @Verseth) - Fix
useId
uniqueness with shared parents + DOM nodes in between (#3773, thanks @marvinhagemeister) - Fix case where keyed children would get removed (#3779, thanks @JoviDeCroock)
- Use
Object.is
in useSyncExternalStore (#3776, thanks @zalishchuk)
Maintenance
- Consolidate benchmark workflow steps into a single reusable workflow (#3782, thanks @andrewiggins)
- Upgrade bench dependencies (#3778, thanks @andrewiggins)
- Upgrade workflow actions (#3777, thanks @andrewiggins)
Bug Fixes
- Fix
setState
order (#3763, thanks @JoviDeCroock) - Fix duplicate ids with
useId
when Fragments are involved (#3758, thanks @marvinhagemeister)
Types
- Fix props not spreadable to
<input>
elements (#3764, thanks @mwszekely)
Bug Fixes
- Fix webpack error when trying to import
compat/package.json
(#3755, thanks @akselander) - Fix nested fragments swapped incorrectly on conditional swap (#3738, thanks @JoviDeCroock)
- Avoid synchronously adding setState callbacks (#3743, thanks @JoviDeCroock)
- Fix signals not supported in HTML + SVG TypeScript definitions (#3747, thanks @marvinhagemeister)
- Only remove nested DOM elements on unmount when necessary (#3741, thanks @developit)
- Don't discard prop updates when nested state update is immediately cancelled (#3739, thanks @JoviDeCroock)
- Align TypeScript definitions from react to refs and forward refs (#3713, thanks @PodaruDragos)
- Add missing
"types"
field forpreact/debug
(#3732, thanks @marvinhagemeister) - Fix falsy data attributes not working (#3720, thanks @JoviDeCroock)
- Ensure
_mask
property always has the same name in distributed version (#3721, thanks @JoviDeCroock)
10.11.0
New Hook: useId
Today we are announcing a new hook: useId
. This hook creates stable unique identifiers that are consistent between server-side rendering (using preact-render-to-string) and client-side hydration. The useId()
hook is primarily useful for generating identifiers for attributes like aria-labelledby
and <label for="...">
.
To enable useId()
to generate consistent unique identifiers, please ensure you are using preact-render-to-string version 5.2.4 or newer for server-side rendering.
(#3583, thanks @JoviDeCroock)
Fixes
- Fix memory leak by cleaning up
_parent
,_dom
and__hooks
after unmount (#3709, thanks @JoviDeCroock) - Fix case where the
ref
property could be omitted from reused VNodes (#3696, thanks @JoviDeCroock) - Pass
errorInfo
touseErrorBoundary
callback (#3689, thanks @marvinhagemeister) - Fix typescript definition for
class | className
(#3711, thanks @PodaruDragos)
Maintenance
- Fix the mac arm build (#3697, thanks @gengjiawen)
- Fix published JS formats after #3697 (#3702, thanks @rschristian)
- Add todo benchmark and add a proxy package that uses preact/hooks (#3708, thanks @JoviDeCroock)
- Add deprecation notice to
render()
'sreplaceNode
argument (#3700, thanks @rschristian) - Improve types for bare
createElement()
andh()
calls (#3690, thanks @JoviDeCroock) - Add test for useId (#3716, thanks @JoviDeCroock)
Fixes
- allow function component with children (#3676, thanks @JoviDeCroock)
- ensure we iterate over all hooks (#3675, thanks @JoviDeCroock)
Fixes
- fix hooks calling shouldComponentUpdate without context (#3671, thanks @developit)
- fix case where we set SCU multiple times (#3670, thanks @JoviDeCroock)
- fix sync-external-store with zustand (#3663, thanks @JoviDeCroock)
Fixes
- fix
useSyncExternalStore
relying on changed render values (#3655, thanks @JoviDeCroock) - avoid crashing due to __hooks being null (#3651, thanks @JoviDeCroock)
Bug Fixes
- Fix infinite loop in
radix-ui
which enqueues multiple state updates in the same tick (#3645, thanks @JoviDeCroock ) - Fix effects run for suspended components in rare instances (#3643, thanks @JoviDeCroock )
- Fix
useSyncExternalStore
not working with function values (#3633, thanks @marvinhagemeister ) - Defer bailing out of updates to the render phase to align with React (#3621 + #3623, thanks @JoviDeCroock )
- Fix some SVG attributes applied with wrong casing (#3615, thanks @iminside)
Maintenance
- Update
esbuild
(#3630, thanks @marvinhagemeister ) - Make demo compatible with node 16 and 18 (#3617, @gengjiawen )
Feature
- Microtick —> setTimeout for debouncing renders (mirror change for setTimeout debounce #3608, thanks @JoviDeCroock)
We changed our debounce of our rendering to setTimeout!
Why? We've batched using microtasks for the past few major versions because it benchmarked well. This had a side-effect of flushing batched renders between event handlers, which can cause some strange behavior:
<input
type="checkbox"
onChange={onChange}
checked={true}
onClick={onClick}
/>
An additional benefit of this change is that code causing an infinite rendering loop will no longer result in an unresponsive browser tab. Rendering in a loop is now capped to the browser's maximum timer frequency (~250Hz), which makes it possible to pause and debug the code triggering an accidental loop.
Feature
We are adding support for the newly added React 18 hooks (apart from useId
) (#3568, thanks @JoviDeCroock)
FIxes
- Adding types for 'part' attribute (#3595, thanks @rschristian)
- prevent _suspended and _force from colliding (#3585, thanks @JoviDeCroock)
Enhancements
- Add support for svg property shape-rendering (#3577, thanks @DannyvanderJagt)
- Remove setState on unmounted component warning (#3576, thanks @ekwoka)
Fixes
- Fix allow return
undefined
inuseMemo
after skipped render (#3580, thanks @marvinhagemeister) - Fix incorrect
useMemo
return value after skipped render (#3579, thanks @marvinhagemeister) - Commit hooks in options.diffed (#3578, thanks @JoviDeCroock)
- restrict "oninputCapture" conversion to just "oninput" vs "oninput*" (#3573, thanks @jramanat-oracle)
Improvements
- Improve unit tests to cover fix on #3573 (#3574, thanks @marconi1992)
- Add
_pendingValue
tomangle.json
(#3575, thanks @marvinhagemeister)
Features
- Add export maps to the subpackages (#3565, thanks @JoviDeCroock)
- Ensure both onchange and oninput callbacks are executes when typing (#3562, thanks @marconi1992)
- Make createRoot / hydrateRoot compatible with React spec (#3560, thanks @3846masa)
- Implement state settling in X (#3553, thanks @JoviDeCroock)
Maintenance
- Fix size CI failing on node version missmatch (#3563, thanks @JoviDeCroock)
Improvements
- Add
server.browser.js
(#3544, thanks @JoviDeCroock) - Add
textPath
SVG type (#3546, thanks @backmeupplz)
Improvements
- improve compat types (#3534, thanks @JoviDeCroock)
- support nodenext in TypeScript 4.7 (#3513, thanks @ilogico)
- add missing containerInfo to portals (#3508, thanks @JoviDeCroock)
Fixes
- fix cleanup of
debounceRendering
hook after exceptions (#3530, thanks @robertknight)
Maintenance
- fix Snyk sponsor link (#3533, thanks @developit)
- add Snyk to sponsors (#3532, thanks @developit)
- remove git.io usages (#3528, thanks @mhmdanas)
- fixes broken Slack shield in README (#3516, thanks @schalkventer)
Features
- Add new react-dom/client entry to compat (#3506, thanks @JoviDeCroock)
Fixes
- Simplify forwardRef and fix empty ref object (#3497, thanks @developit)
Features
- Add support for
errorInfo
(#3452, thanks @marvinhagemeister ) - Allow for passing in multiple refs through forwardRef (#3494, thanks @JoviDeCroock)
Bug Fixes
- Fix Incorrect translation of
xlink:href
attribute -> hhref (#3453, thanks @pguilbert) - Fix swapped jsx runtime
__source
and__self
arguments (#3459, thanks @marvinhagemeister) - Ensure consistent format order for package entries (#3489, thanks @marvinhagemeister)
- Reset
useImperativeHandle
ref tonull
when the component get unmounted (#3487, thanks @deadem)
Typings
- Add missing
defaultValue
anddefaultChecked
typings (#3464, thanks @ilogico)
Maintenance
- Fix test not cleaned up properly (#3457, thanks @marvinhagemeister
- Fix fake timers not being reset on test failure (#3458, thanks @marvinhagemeister)
- Remove unused devDependency (#3460, thanks @marvinhagemeister)
- Update test dependencies (#3467, thanks @marvinhagemeister)
- Improve karma test console logging (#3475, thanks @marvinhagemeister)
- Fix karma error traces not being source mapped (#3476, thanks @marvinhagemeister)
As usual we recommend all users to upgrade.
Bug Fixes
- Fix cursor reset in Safari in input field while typing by (#3448, #3450, thanks @marvinhagemeister)
- Make sure
compat
is triggered in newjsx-runtime
(#3445, thanks @Austaras)
Fixes
- fix effect ordering (#3416, thanks @JoviDeCroock)
- Normalize CompositionEvent listeners in preact/compat (#3430, thanks @hpneo)
Types
- Change type of for better TypeScript compatibility with @emotion/react and @types/react. (#3431, thanks @rolftimmermans)
Maintenance
- Use onInput instead of onChange in the README example (#3420, thanks @matthiask)
- remove malfunctioning csb ci (#3417, thanks @JoviDeCroock)
- Fix instructions for npm tag in CONTRIBUTING (#3380, thanks @andrewiggins)
- Fix typo in release workflow (#3379, thanks @andrewiggins)
- Automate building npm package for release (#3378, thanks @andrewiggins)
Fixes
- Fire useEffect in reverse component depth order (#3354, thanks @developit)
- Map onFocus/onBlur to onfocusin/onfocusout (#3355, thanks @developit)
Maintenance
- Add test for useEffect ordering with useMemo (#3360, thanks @andrewiggins)
Fixes
- Handle hooks that throw during cleanup (#3345, thanks @JoviDeCroock)
- Include all package.json files in the export-maps (#3344, thanks @developit)
Fixes
- Fix switch check for excessDomChildren (fixes IE11) (#3342, thanks @JoviDeCroock)
Maintenance
- Fix es5 warnings in local test runs (#3340, thanks @developit)
Types
- Adjust raf types (#3323, thanks @JoviDeCroock)
- Suggest fix for useRef-types in hooks (#3222, thanks @JoviDeCroock)
- Add component props to compat exports (#3321, thanks @JoviDeCroock)
Fixes
- Fix className leak (#3279, thanks @JoviDeCroock)
- Support hydrating html comments (#3327, thanks @JoviDeCroock)
Maintenance
- Fix tests in IE11 (#3264, thanks @developit)
- Add jsx(-dev)-runtime to the export maps (#3320, thanks @JoviDeCroock)
Fixes
- Skip rendering contents on the client in compat (#3238, thanks @developit)
- Nested Suspended trees may be missing _children (#3260, thanks @developit)
- Manage camel-cased dominant-baseline attribute in preact/compat (#2859, thanks @nmondon)
- Restrict camelCase prop renaming to non-custom elements (#3259, thanks @jramanat-oracle)
- Fix bug in chrome where select values continuously rerender (#3226, thanks @JoviDeCroock)
- Avoid leaking internal vnodes (#3106, thanks @developit)
Types
- Fix ref typing of forwardRef (#3214, thanks @itkrt2y)
- Add
focusin
&focusout
to type definitions (#3257, thanks @boarwell) - Add
onBeforeInput
attribute to type definitions (#3256, thanks @boarwell) - Add missed HTML attributes in the TS typings (#3246, thanks @rschristian)
Maintenance
- Update babel.config.js (#3265, thanks @RRDAWLX)
- Delete redundant previousComponent in hooks (#3271, thanks @RRDAWLX)
- Update test dependencies (#3255, thanks @marvinhagemeister)
Features
- Compat: Add
flushSync
(#3094, thanks @zephraph)
Bug Fixes
- Prevent eager child removal (#3210, thanks @JoviDeCroock)
- Compat: Update Fake React Version (#3189, thanks @tim-on-github)
- Fix
react-spring
error caused by augmented function contexts (#3165, thanks @developit) - Use
Array.prototype.slice.call
for children arguments (#3143, thanks @fzzle) - Improve performance of
vnodeId
generation (#2978, thanks @developit) - Fix: should override
children
ifnull
is provided as an argument (#3091, thanks @clyfish)
Size
- refactor(diff-index): reuse
i
to reduce size (-32b) (#3193, thanks @liuarui) - Simplify unmount logic (#3120, thanks @andrewiggins)
Typings
- Fix type definitions (#3191, thanks @craftedsystems)
- Fix
undefined
initializer case foruseState
type (#3185, thanks @rschristian) - Make typings
deno
compatible (#3079, thanks @lucacasonato) - Change typing of
event.this
to benever
(#3147, thanks @JoviDeCroock) - Update signature of
lazy
to reflect behavior (#3139, thanks @JonasKruckenberg) - Improve typing of
forwardRef
(#3144, thanks @cmlenz) - Fix the
useRef
typing to includeundefined
when called without initial value (#3056, thanks @cmlenz)
Maintenance
- Docs: Removing suggestion to install Preact CLI (#3204, thanks @rschristian)
- Upgrade
karma-esbuild
to support M1 chips (#3153, thanks @marvinhagemeister) - Rely directly on
performance.now
(#3130, thanks @developit) - Add The Guardian as a Github backer (#3086, thanks @mchv)
- Fix typo in issue template (#3067, thanks @rschristian)
Bug Fixes
- Fix unable to reset
tabIndex
(#3062 + #3064, thanks @marvinhagemeister) - Add ESM entry for
compat/server
(#3059 + #3061, thanks @marvinhagemeister) - Fix unable to render
bigint
numbers (#3010, thanks @marvinhagemeister) - Fix reordering issue of memoized component when the component initially render null (#2988, thanks @tanhauhau)
Types
- Add
decoding
attribute (#3054, thanks @sumanthratna) - Add missing
SVGFEFunc
types (#3043, thanks @rschristian)
Maintenance
- Update issue templates (#3058, thanks @marvinhagemeister)
- Update esbuild to natively support Apple's M1 chip (#3028, thanks @marvinhagemeister)
- Create separate trace log directories per benchmark (#3024, thanks @andrewiggins)
- Reduce redundant preparation in bench scripts (#3013, thanks @andrewiggins)
- Tests: Fix stale watch cache (#3012, thanks @marvinhagemeister)
- Tests: Reduce CPU usage in watch mode (#3011, thanks @marvinhagemeister)
- Tests: Fix Chrome 88 stack traces displayed wrong in terminal (#3008, thanks @marvinhagemeister)
- Upgrade tachometer and add script to analyze browser trace logs (#3005, thanks @andrewiggins)
- Use
options.unmount
instead of overridingcomponent.componentWillUnmount
(#2919, thanks @tanhauhau) - Update esbuild + karma-esbuild (#2991, thanks @marvinhagemeister)
- Add a few minor tests (#2981, thanks @43081j)
This release includes an enhancement to our devtools integration. Via a babel plugin you can get more readable hook names to show up in devtools instead of dozens of useState
hooks in devtools. Check out https://github.com/preactjs/babel-plugin-transform-hook-names for more information.
Before:
After:
Bug Fixes
- Compat: Fix
defaultValue
not applied when value==null/undefined
(#2957, thanks @marvinhagemeister) - Fix HTML comments breaking hydration (#2956, #2960 thanks @marvinhagemeister and @developit)
Maintenance
- Tests: Improve
console.logs
(#2959, thanks @marvinhagemeister) - Remove redundant benchmark initialization (#2966, thanks @andrewiggins)
- Fix pr-reporter condition (#2964, thanks @andrewiggins)
- Report benchmarks on PRs from forks (#2961, thanks @andrewiggins)
- Update size action to only run when src files change (#2962, thanks @andrewiggins)
- Use artifact flow to report benchmarks results (#2953, thanks @andrewiggins)
:chart_with_upwards_trend: Bug Fixes
- Fix unable to set
contentEditable
tofalse
(#2938, #2939 thanks @marvinhagemeister + @developit) - Fix
compat/jsx-dev-runtime
missing in package (#2931, thanks @marvinhagemeister)
:golf: Code golfing
- Golf element diffing [-17b] (#2942, thanks @developit)
- Pass all props to
createElement
instead of justis
[-5b] (#2943, thanks @developit) - Use try/catch for properties instead of an allow list, remove
xlink:
(#2939, thanks @developit) - Simplify diffChildren's handling of excessDomChildren and oldDom (#2941, thanks @andrewiggins)
:hammer_and_wrench: Maintenance
- Tests: Alias
react
topreact/compat
(#2946, thanks @marvinhagemeister) - Separate benchmarks into their own workflow (#2944, thanks @andrewiggins)
- Simplify top-level render and remove dead code (#2940, thanks @andrewiggins)
- Tests: Fix stack traces not sourcemapped (#2935, thanks @marvinhagemeister)
- Fail build on missing compat entries in files entry (#2934, thanks @marvinhagemeister)
- Add
workflow_dispatch
and restructure branch trigger (#2933, thanks @andrewiggins) - Tests: Fix vscode breakpoints not being hit (#2932, thanks @marvinhagemeister)
- Fix incorrect sourcemap line mapping in tests (#2929, thanks @marvinhagemeister)
Bug Fixes
- Fix
contentEditable
throwing when set to undefined/null (#2927, thanks @marvinhagemeister) - Compat: Add basic shims for some scheduler functions (#2912, thanks @marvinhagemeister)
- Add
jsx-dev-runtime
package entry (#2920, thanks @sventschui) - Avoid overriding render method in
Suspense
(#2917, thanks @andrewiggins) - Fix updating suspended component (#2910, thanks @tanhauhau)
Maintenance
- Fix
Portal
test not cleaning up container (#2925, thanks @marvinhagemeister) - Fix tests in IE11 (#2924, thanks @marvinhagemeister)
- Fix karma IE11 target containing ES2015 syntax (#2923, thanks @marvinhagemeister)
- Upgrade
sinon
dependencies to fix IE11 Promise error (#2922, thanks @marvinhagemeister) - Fix SauceLabs runner (#2918, thanks @andrewiggins)
- Fix
karma
benchmarks not compiling (#2914, thanks @marvinhagemeister) - Remove
babel-loader
(#2911, thanks @andrewiggins) - Remove unused comment (#2909, thanks @marvinhagemeister)
Happy New Year to everyone 🎉 Let's kick of the year with a few welcome bug fixes regarding preact/compat
👍
Bug Fixes
- Fix bug when re-rendering a suspended hydration node (#2903, thanks @andrewiggins)
- Fix devtools error with portals (#2904, thanks @JoviDeCroock)
- Fix child reordering with
memo
(#2896, thanks @andrewiggins)
Maintenance
- Replace webpack with esbuild + babel in karma test runner(#2907, thanks @marvinhagemeister)
- Rename "coverage" env to "COVERAGE" (#2906, thanks @marvinhagemeister)
- Ensure expression is not marked for removal (#2905, thanks @marvinhagemeister)
- Prepare test code to be run in ES2015+ environments (#2901, thanks @marvinhagemeister)
- Fix invalid jsx comment (#2902, thanks @marvinhagemeister)
- Fix console.log not showing up in browser (#2900, thanks @marvinhagemeister)
- Improve hydration tests (#2899, thanks @andrewiggins)
- Add support for pretty printing karma console logs (#2893, thanks @marvinhagemeister)
This is probably the last release for 2020. Thank you everyone for the amazing contributions over the year and we can't wait to see where Preact is going in 2021! Lot's of interesting ideas are being worked on 🎉
Bug Fixes
- Correct
_nextDom
pointer if it is being unmounted (#2889, thanks @andrewiggins) - Updating
/compat/server
exports to work with import/export syntax and webpack 5 (#2873, thanks @SomethingSexy) - Remove arguments warning for
useMemo
/useCallback
hooks (#2870, thanks @afzalsayed96) - Use strict equality checks when comparing
VNode
type (#2855, thanks @andrewiggins) - Fix
ref
not being removed fromprops
withjsx-runtime
(#2840, thanks @marvinhagemeister) - Compat: Don't convert
onchange
tooninput
forinput[type=range]
in IE11 (#2817, thanks @gcraftyg)
Types
- Improve
JSDoc
comments (#2883, thanks @andrewiggins) - Use
CSSStyleDeclaration
for CSS property list (#2869, thanks @developit) - Add
readonly
attribute (#2868, thanks @rschristian) - Add
defaultValue
for select tag (#2848, thanks @Rafi993) - Update
_original
typings (#2830, thanks @marvinhagemeister) - Update
csstype
from version 2 to version 3 (#2829, thanks @bz2)
Other
- SimplifyPortal implementation (#2890, thanks @marvinhagemeister, @developit)
- Simplify
vnode
re-use detection (-2 B) (#2863, thanks @marvinhagemeister) - Save 6 Bytes (#2844, thanks @marvinhagemeister)
- Move child reodering to
diffChildren
(#2813, thanks @JoviDeCroock)
Maintenance
- Add discussions and a csb template (#2875, thanks @JoviDeCroock)
- In benches, abstract framework differences with
createRoot
API (#2866, thanks @andrewiggins) - Add filter benchmark (#2851, thanks @marvinhagemeister)
- Update benchmarks (#2865, thanks @andrewiggins)
- Add preactjs-gh-sponsor account to
FUNDING.yml
(#2861, thanks @JoviDeCroock) - Upgrade
devDependencies
(#2856, thanks @andrewiggins) - Add package tags (#2841, thanks @developit)
- Trial codesandbox-ci (#2819, thanks @JoviDeCroock)
Bug Fixes
- Throw when hook is invoked outside of render (#2816, thanks @marvinhagemeister)
- Make
jsx-runtime
work when using an alias (#2805, thanks @JoviDeCroock) - Allow rendering from an effect (#2804, thanks @JoviDeCroock)
Types
- Add
animateTransform
tag type (#2822, thanks @HuHguZ) - Add
displayName
to context (#2820, thanks @max-voronov) - Improve
style
attribute types (#1797, thanks @mnkhouri) - General JSX types export for
jsx-runtime
, fixes TS4.1 compatibility (#2811, thanks @ddprrt) - Make
ref
types' current property non-optional (#2803, thanks @ivantm)
Maintenance
- Remove circular
vnode
reference and golf implementation (#2517, thanks @JoviDeCroock) - Add hydration suspend tests (#2755, thanks @andrewiggins)
- Fix prototype spies not being reset in tests (#2823, thanks @marvinhagemeister)
Bug Fixes
- Reset hooks state when
Suspense
triggers (#2796, thanks @JoviDeCroock) - Run parent effects when child throws (#2794, thanks @sventschui)
Typings
- Fix memo function types definition (#2793, thanks @dzhykaiev)
tl;dr: Bug-Fix only release that should get rid of the last className edge cases. We encourage everyone to upgrade.
Despite our effort to account for all edge cases regarding className
handling in preact/compat
, we got some reports of some missed ones. This release corrects those :tada:
This release contains a fix to increase compatibility with next.js that ensures that the error overlay will show up.
Bug Fixes
- Emit error event for errors handled by an error boundary (#2784, thanks @sventschui)
- Fix
className
descriptors on Elementvnodes
(#2786, thanks @developit) - Give precedence to
className
overclass
(#2782, thanks @JoviDeCroock)
This release fixes a regression in regards to class/className
handling in preact/compat
. We encourage everyone to upgrade.
Bug Fixes
- Fix
className
normalization (#2774, thanks @JoviDeCroock) - Fix edge cases for thrown
Promises
in Suspense (#2776, thanks @kitten)
Maintenance
- Replace custom script with
check-export-map
(#2777, thanks @marvinhagemeister) - Upgrade bench infra and add tachometer PR reporter (#2775, thanks @andrewiggins)
- Optimizations for preact/jsx-runtime (#2771, thanks @developit)
New JSX-runtime functions
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.
Features
- Add
jsx-runtime
support (#2764, thanks @JoviDeCroock, @marvinhagemeister) - Implement Suspend & Resume for both hydration and new tree construction (#2754, thanks @developit)
Bug Fixes
- Fix unable to set progress value to
0
(#2757, thanks @marvinhagemeister) - Fix capturing and non-capturing listeners on the same element (#2740, thanks @devongovett)
- Prevent cursor jumps inside
contenteditable
(#2701, thanks @sventschui) - Add length check for hooks dependency array (#2729, thanks @JoviDeCroock)
- Fix rendering children as zero number (#2725, thanks @JiLiZART)
- Avoid assigning to readonly
style
(#2723, thanks @JoviDeCroock)
Maintenance
- Add mangle key for
_suspended
(#2765, thanks @marvinhagemeister) - Compat Optimizations (v11 backport) (#2752, thanks @developit)
- Add version check to issue template (#2731, 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:
Golfing
- Remove all the bytes (#2665, thanks @developit)
Bug Fixes
- Fix state turned
readonly
in update fn (#2717, thanks @marvinhagemeister) - Fix deprecation warnings flooding console with
preact/debug
(#2711, thanks @marvinhagemeister) - Initialize normalized props with
undefined
instead ofnull
inpreact/compat
(#2695, thanks @aralroca) - Add React "secret or fired" shim for
react-relay
(#2692, thanks @marvinhagemeister) - Properly unset
href
on nullish value (#2693, thanks @marvinhagemeister) - Go back to
undefined
as default value foruseRef
(#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)
Typings
- Automatically add
dom
lib (#2713, thanks @Gerrit0) - Update
useDebugValue
typings to align with React (#2699, thanks @leader22) - Remove
useErrorBoundary
compat types (#2631, thanks @38elements) - Add support for
IntrinsicElements
inComponentProps
(#2680, thanks @remcohaszing)
Maintenance
- Update slack link in
CONTRIBUTING.md
(#2702, thanks @marvinhagemeister) - Fix invite link (#2697, thanks @JoviDeCroock)
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:
Bug Fixes
- Avoid touching DOM-attributes during hydration (#2679, thanks @JoviDeCroock)
- Fix incorrect
download
attribute handling (#2674, thanks @marvinhagemeister) - Allow the same component to be suspended multiple times (#2661, thanks @tanhauhau)
- Allow resolve promise after suspense unmounted (#2664, thanks @tanhauhau)
- Throw when hook is used inside effect (#2672, thanks @marvinhagemeister)
- Fix incorrect text node handling in
diffElementNodes
(#2658, thanks @perseveringman) - Default
useRef
tonull
(#2648, thanks @JoviDeCroock) - Fix calling
setState
inconstructor
(#2640, thanks @sventschui)
Types
- Change argument of
useRef
to optional (#2651, thanks @38elements) - Updated
capture
definition. (#2643, thanks @JonathanBristow) - Update
preact/compat
types (#2628, thanks @jeremy-coleman)
Maintenance
- Run benches on linux VMs (#2595, thanks @andrewiggins)
- Fix
package.json
"authors" field (#2635, thanks @developit)
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:
Bug Fixes
- Initialize
children
if they'renull
in suspense (#2570, thanks @sventschui) - Fix case where
textarea
doesn't reset state (#2615, thanks @JoviDeCroock) - Fix passing
null
toforwardRef
(#2600, thanks @JoviDeCroock)
Typings
- Make
strokeMiterlimit
accept a number as well (#2620, thanks @lfamorim) - Add
feDropShadow
definition (#2609, thanks @Somnid)
Maintenance
- Add missing
LICENSE
files and fix submodule names (#2611, thanks @hbroer) - Fix typo in
CONTRIBUTING.md
(#2603, thanks @futantan) - HTTPS fix for README image (#2602, thanks @developit)
- Run same workflow on PR and master push (#2601, thanks @andrewiggins)
This is a bugfix-only release and updating is seamless. We encourage everyone to do so :+1:
Bug Fixes
- Prevent
Suspense
from inadvertently modifying sharedComponent
class (#2594, thanks @andrewiggins) - Fix
Fragment
edge case (#2551, thanks @JoviDeCroock) - Check for existence of
requestAnimationFrame
while cancelling effects it (#2573, thanks @Hydrophobefireman) - Handle
setState
in render (#2565, thanks @jamesb3ll) - Fix
forwardRef
passing object instead of null (#2567, thanks @marvinhagemeister) - Normalize value prop on textareas in
compat
(#2558, thanks @btk5h) - Prevent
useReducer
from mutating the previous returned result (#2550, thanks @JoviDeCroock)
Maintenance
- Improve code coverage (#2596, thanks @andrewiggins)
- Optimize unpkg entry: Commonjs plus globals default export (#2261, thanks @developit)
- Share build output between action jobs (#2579, thanks @andrewiggins)
- Add TypeScript for extending JSX types with custom elements (#2581, thanks @andrewiggins)
- Update Node version in actions and format YAML files using prettier (#2577, thanks @andrewiggins)
- Add GitHub action to run benches (#2560, thanks @andrewiggins)
- Add many_updates benchmark (#2559, thanks @andrewiggins)
- 🏌️♂️ rAF check (#2555, thanks @developit)
- put rerenderCount on the Component prototype (#2552, thanks @JoviDeCroock)
- Use "babel-plugin-transform-rename-properties" to consistently mangle properties (#2548, thanks @andrewiggins)
This is a hotfix for today's 10.4.2 release that:
- addresses an issue with mobx-react (#2541, thanks @marvinhagemeister)
- fixes a regression in useEffect cleanup callbacks (#2542, thanks @fuzetsu)
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!
Introducing prefresh (experimental)
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!
Snowpack template
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
Preact sightings
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!
Bug Fixes
- Add noop
React.StrictMode
tocompat
(#2529, thanks @developit) - Use latest reducer function in
useReducer
(#2526, thanks @hadeeb) - Improve
IS_NON_DIMENSIONAL
for compatibility with animation-iteration-count (#2523, thanks @viko16) - Polyfill prototype setter in
debug
(#2514, thanks @JoviDeCroock) - Fix
hydrate
export incompat
(#2511, thanks @hadeeb) - Fix creating multiple roots from
useEffect
(#2493, thanks @JoviDeCroock)
Types
- Add
StrictMode
tocompat/src/index.d.ts
(#2530, thanks @38elements) - Add
loading
attribute toHTMLAttributes
TypeScript interface (#2521, thanks @gerardo-rodriguez)
Maintenance
- Fix
CONTRIBUTING.md
indentation (#2528, thanks @Vincent-Carrier) - Fix test on IE11 by wrapping the
spy
helper (#2524, thanks @JoviDeCroock) - Remove unnecessary cloning of props (#2516, thanks @hadeeb)
- Iteratively diff children and convert array children to
Fragments
(#2507, thanks @andrewiggins) - Update focus tests to better match user behavior (#2506, thanks @andrewiggins)
- IE11+ -> IE11 (#2499, thanks @38elements)
- Reorganize render test file (#2487, thanks @andrewiggins)
- golf effect cleanup (#2494, thanks @JoviDeCroock)
- Remove
processingException
check (#2483, thanks @JoviDeCroock) - Reduce unnecessary DOM attribute reads (#2486, thanks @andrewiggins)
- Remove unnecessary
excessDomChildren
creation (#2491, thanks @andrewiggins) - Add update benchmark from
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.
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.
Bug Fixes
- Add support for hooks inspection via devtools (#2480, thanks @marvinhagemeister)
- Make warn effectively warn instead of throwing (#2477, thanks @JoviDeCroock)
- Support node13 (#2451, thanks @JoviDeCroock)
- Use
setProperty
to set "value" and "checked" properties (#2472, thanks @andrewiggins) - Normalize props on
cloneElement
(#2469, thanks @JoviDeCroock) - Set value/checked on custom-elements (#2465, thanks @JoviDeCroock)
- Add support for context
displayName
(#2454, thanks @marvinhagemeister)
Typings
- Add
<marquee>
typings (#2466, thanks @developit) - Account for
defaultProps
when wrapping components withmemo
(#2461, thanks @davidje13)
Maintenance
- Run benchmarks with v8, master, and local builds (#2475, thanks @andrewiggins)
- Reduce number of builds in actions (#2476, thanks @andrewiggins)
- Add npm prepare script (#2473, thanks @andrewiggins)
- Upgrade devtools adapter (#2471, thanks @marvinhagemeister)
- Tachometer benchmarks (#2462, thanks @andrewiggins)
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:
Strictly equal vnodes
bail out of render
When 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:
hydrate falls back to render for new subtrees
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.
Features
- Implement strict-equality for
vnodes
(#2386, thanks @JoviDeCroock) - Fallback to render when subtrees are inserted on
hydration
(#2438, thanks @JoviDeCroock) - Add owner stack for invalid child warning (#2416, thanks @marvinhagemeister)
Bug Fixes
- Fix error messages logged by failed prop type checks (#2434, thanks @robertknight)
- Skip
setProperty
for known bypass cases (key, children) (#2213, thanks @developit) - Improve handling of exceptions thrown during
act
callback (#2433, thanks @robertknight) - Ensure
ref
is mutable even if a DOM node is inserted into it (#2422, thanks @JoviDeCroock) - Fix Context not re-rendering when reset to
defaultValue
(#2420, thanks @JoviDeCroock) - Disable normalization of string vnodes (#2410, thanks @JoviDeCroock)
Typings
- Update
act
type signature (#2444, thanks @ddayguerrero) - Add
_patchedLifecycles
tocompat/src/internal.d.ts
(#2408, thanks @38elements)
Maintenance
- Docs: Fix simple typo, stucture -> structure (#2440, thanks @timgates42)
- Fix CONTRIBUTING typo (#2417, thanks @futantan)
- Use double equal with
typeof
(#2409, thanks @polemius) - Enable saucelabs-connect (#2411, thanks @developit)
- Move from Travis to Github Actions (#2401, thanks @JoviDeCroock)
This is a maintenance release, upgrading should be free, please do report it in case you encounter any issues.
render-queue sorting
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.
material-ui integration
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.
Fixes:
- Fix mui Popover integration (#2403, thanks @JoviDeCroock)
- Fix defaultValue with re-render (#2392, thanks @aralroca)
- Sort new renderqueue items (#2396, thanks @jviide)
Maintenance:
- Fix stopPropagation override for IE11 (#2390, thanks @JoviDeCroock)
- Use createEvent since InputEvent and new Event won't work in IE11 (#2400, thanks @JoviDeCroock)
- Fix useErrorBoundary hook callback type (#2397, thanks @Sasha-Sorokin)
- Update cloneElement typings (#2388, thanks @ddayguerrero)
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!
Much improved conditional rendering
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:
Improved SVG attribute casing
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:
Preact sightings
@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:
Features
- Compat: Add
isPropagationStopped
fn to event (#2378, thanks @reznord) - Compat: Add
isDefaultPrevented
fn to event (#2377, thanks @teodragovic) - Large performance boost in
preact/debug
(#2362, thanks @developit)
Bug Fixes
- Fix
event.isPropagationStopped()
(#2380, thanks @38elements) - Fixed SVG attribute names not being converted to the correct attribute names in the DOM. (#2366, thanks @steveharrison)
- Fix incorrect warning on
setState
insidecomponentWillMount
(#2367, thanks @marvinhagemeister) - Fix static hydration (#2365, thanks @JoviDeCroock)
- Fix hook outside of component test (#2359, thanks @JoviDeCroock)
- Remove warning for
useEffect/useLayoutEffect
(#2358, thanks @JoviDeCroock) - Improve
null
placeholder DOM placement (#2355, thanks @andrewiggins)
Typings
- Fix
options.event
type definition (#2381, thanks @38elements)
Maintenance
- Add comment to clarify seemingly redundant string concatenation (#2369, thanks @mhmdanas)
- Rename some variables to increase legibility (#2361, thanks @andrewiggins)
- Combine searches in
excessDomChildren
into the same code block (#2356, thanks @andrewiggins) - Fix failing test by defaulting to empty array (#2353, thanks @JoviDeCroock)
- Add new test file for
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:
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 checked
As usual thank you so much for everyone who helped make Preact better by contributing code or reporting issues! You all rock :+1:
Bug Fixes
- Add support for
false
value in aria-attributes (#2347, thanks @marvinhagemeister) - Remove array provided to callback in
React.Children.map
and.forEach
(#2326, thanks @mhmdanas) - Fix
React.Children.map/forEach
missing index (#2322, thanks @JoviDeCroock)
Typings
- Match
useErrorBoundary
type withcomponentDidCatch
(#2332, thanks @intrnl) - Fix incompatible
ref
typing with ReactElement (& popular react libraries) (#2099, thanks @xiel) - Make
useErrorBoundary
's callback param optional (#2320, thanks @intrnl)
Maintenance
- Fix failing
useImperativeHandle
tests (#2346, thanks @marvinhagemeister) - Create
ISSUE_TEMPLATE.md
(#2342, thanks @JoviDeCroock) - Node "exports" adjustments (#2327, thanks @guybedford)
- Add
package.json
topackage.exports
(#2319, thanks @MylesBorins)
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.
Run tests against the minfied production artifact
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:
A new size bot
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:
Changelog
Bug Fixes
- Fix
className
not being applied when set to an emptystring
withpreact/compat
(#2309, thanks @JoviDeCroock) - Run karma tests against build output (#2300, thanks @andrewiggins) :heart:
- Fix: Resolves Node submodule subpath error (#2304, thanks @4cm4k1)
Maintenance
- Add to
umd
and make browser a modularexport
for future bundlers (#2311, thanks @JoviDeCroock) - Add root exports (#2310, thanks @JoviDeCroock)
- Removes warning from tests by removing console.log in render.test.js (#2305, thanks @theZieger)
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:
Features
- Include support for customised
built-in
elements (#2266, thanks @defx) - Upgrade devtools adapter to support Profiler and bring back
preact/devtools
import (#2246, thanks @marvinhagemeister)
Bug Fixes
- Suspended components should rerender through
shouldComponentUpdate
(#2125, thanks @andrewiggins) - Reduce reads of
dom.nextSibling
(#2294, thanks @andrewiggins) - Preserve state when using placeholders (#2295, thanks @andrewiggins)
- Fix
Children.map
not flattening result (#2287, thanks @marvinhagemeister) - Fix error when setting
size
to an invalid value (#2285, thanks @marvinhagemeister) - Fix wrong SVG attribute for
clipPathUnits
(#2251, thanks @friebe) - Fix both
class
andclassName
being enumerable (#2280, thanks @marvinhagemeister) - Fix
className
patch not applied to props (#2279, thanks @marvinhagemeister) - Bailout when hook throws an error (#2193, thanks @JoviDeCroock)
- Avoid removing existing dom nodes on subsequent
replaceNode
calls (#2274, thanks @JoviDeCroock) - Fix
shouldComponentUpdate
getting called onsetState
afterforceUpdate
(#2258, thanks @laino) - Remove
process.env.NODE_ENV
check frompreact/debug
which broke browsers (#2257, thanks @marvinhagemeister)
Types
- Allow
null
as an initial value foruseRef
(#2281, thanks @armujahid)
Maintenance
- Rename
_lastDomChildSibling
to_nextDom
(#2297, thanks @andrewiggins) - Improve code coverage (#2299, thanks @andrewiggins)
- Update
mangle.json
with Suspense prop rename (#2298, thanks @andrewiggins) - Fix SVG polygon test failing on IE 11 (#2288, thanks @marvinhagemeister)
- Try out new node submodule exports (#2283, thanks @JoviDeCroock)
- Add section about reporting bugs (#2278, thanks @marvinhagemeister)
- Improve CONTRIBUTINIG + comments (#2277, thanks @marvinhagemeister)
- Add
size
action (#2270, thanks @developit) - Prevent
postinstall
from running on installation (#2271, thanks @JoviDeCroock) - Add test coverage for
createElement
(#2273, thanks @zubhav) - Fix custom element tests failing in IE (#2272, thanks @marvinhagemeister)
- Fix failing IE test (#2267, thanks @marvinhagemeister)
- Add info for first time contributors (#2265, thanks @marvinhagemeister)
- Add unit tests to check proper component unmounting (#2195, thanks @timon-witt)
- Add
npm ci
to speed up travis (#2255, thanks @JoviDeCroock) - Add
package-lock.json
(#2254, thanks @JoviDeCroock)
This release corrects an issue regarding hydration that was found in yesterdays 10.2.0
release :tada:
Bug Fixes
- Fix duplicate text node with
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 brings two new features and the usual round of bug fixes :100:
New useErrorBoundary
hook
There 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 />;
}
};
Lazy works with non-default export
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:
Features
- Add
useErrorBoundary
hook (#2205, thanks @JoviDeCroock) - Allow
lazy()
usage with non-default imports (#2212, thanks @developit)
Bug Fixes
- Fix incorrect
ref
value on siblingvnodes
(#2217, thanks @JoviDeCroock) - Fix stale closure in error boundary (#2225, thanks @JoviDeCroock)
- Fix
Text
nodes being re-rendered unnecessarily (#2215, thanks @developit) - Shorten and correct
renderToString
dependency error (#2207, thanks @developit) - Support combination of
getDerivedStateFromError
andcomponentDidCatch
(#2200, thanks @JoviDeCroock) - Fix compat hydration (#2206, thanks @JoviDeCroock)
Typings
- Add
onReset/onFormData
to Form Event types (#2209, thanks @thesmartwon)
Maintenance
- More README updates (#2235, thanks @developit)
- Modernize our README (#2232, thanks @JoviDeCroock)
- Update package metadata (#2230, thanks @developit)
- Add more test cases for
Suspense
(#2229, thanks @sventschui) - Fix renderer tests by using
sinon
global (#2220, thanks @JoviDeCroock) - Update JSDoc comments (#2187, thanks @soulhat)
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:
Component Stacks
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:
Features
- Add component stack in debug warnings (#2179, thanks @marvinhagemeister)
Bug Fixes
- Fix
componentWillReceiveProps
not called on child component when parent is queued in the same commit (#2186, thanks @jamesb3ll)
Maintenance
- Workaround for
sinon
esm bundle (#2188, thanks @marvinhagemeister)
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.
Developers, Developers, Developers! :wrench:
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 :1234:
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>
Features
- Add support for preact-devtools (#2148, thanks @marvinhagemeister)
SuspenseList
optimisations (#2121, thanks @jviide)- Add
SuspenseList
component (#2063, thanks @prateekbh)
Bug Fixes
Suspense
should support unmounting suspender (#2134, thanks @sventschui)- Add correct
this
type for event handlers (#2166, thanks @marvinhagemeister) - Prevent crash in IE when setting
type
attribute (#2147, thanks @Rafi993) - Always use lower cased
touch
events incompat
(#2120, thanks @sventschui) - Fix wrong DOM order on suspend inside
Fragment
(#2107, thanks @jviide)
Typings
- Add
onToggle
event to TypeScript defs. (#2151, thanks @xorgy) - Re-export
FunctionComponent
frompreact/compat
(#2087, thanks @jokester) - Fix internal Suspense-related typings (#2117, thanks @jviide)
- Specify valid
dir
property values (#2108, thanks @antonk52)
Golf :golf: :golfing_woman:
- Optimize
createElement
(#2135, thanks @developit) - Rename
useMemo
_callback
to_factory
(+0 B) (#2131, thanks @andrewiggins) - Remove redundant
if
clause in suspense_catchError
(#2119, thanks @sventschui) - Consolidate
VNode
compat options (-62 B) (#2116, thanks @andrewiggins)
Maintenance
- Disable benchmarks on CI (#2167, thanks @marvinhagemeister)
- Fix minor spelling and grammar issue (#2165, thanks @ivanjonas)
- Update perf tests for Preact X and enable on
master
(#2158, thanks @andrewiggins) - Rewrite touch event tests to not use internals (#2157, thanks @andrewiggins)
- Improve test DOM helpers (#2152, thanks @andrewiggins)
- Rewrite some tests to no longer rely on internals (#2132, thanks @andrewiggins)
- Fix cross browser tests assertions (#2127, thanks @andrewiggins)
- Modularize
compat
src and tests (#2124, thanks @andrewiggins) - Add test to cover hooks debug helper (#2115, thanks @andrewiggins)
- Add test for lifecycles and state of a delayed suspending compo… (#2114, thanks @andrewiggins)
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:
Bug Fixes
- Cleanup changing
refs
correctly (#2055, thanks @JoviDeCroock) - Ensure
renderCallbacks
are called whensCU
bails out (#2081, thanks @JoviDeCroock) - Handle the stale
ref
forforwardRef
(#2075) (#2076, thanks @cristianbote)
Golf :golfing_woman:
- Simplify
hook
scheduling logic (-17 B) (#2085, thanks @andrewiggins) - Improve tree-shakeability (-13 B) (#2079, thanks @andrewiggins)
- Simplify ternary expressions (-7 B) (#2049, thanks @andrewiggins)
- Remove CSS custom property check from
IS_NON_DIMENSIONAL
(#2046, thanks @jridgewell)
TypeScript
- Add types for
currentTarget
on event handlers forIntrinsicElements
(#2084, thanks @lukeshiru) - Improve
ref
typings forIntrinsicElements
(#2070, thanks @lukeshiru) - Add
as
html attribute to TypeScript defs (#2068, thanks @jakearchibald)
Maintenance
- Add
funding
field to package.json (#2096, thanks @developit) - Upgrade tests to use Babel 7 (#2094, thanks @andrewiggins)
- Rewrite
createContext
tests to no longer import internal data (#2090, thanks @andrewiggins) - Remove
preact-charts
fromREADME
(#2092, thanks @pmkroeker) - Update
README
section aboutpreact/devtools
(#2091, thanks @peterswallow) - In tests, import code under test by name instead of relative path (#2086, thanks @andrewiggins)
- Replace
__p
to__
inmangle.json
(#2044, thanks @38elements) - Make all
.json
files use 2-space (#2078, thanks @developit) - Adding Intergram to the demos list (#2064, thanks @idoco)
- Improve formatting (#2071, thanks @andrewiggins)
- Improve formatting (#2066, thanks @andrewiggins)
- Add automatic formatting via
prettier
(#2065, thanks @marvinhagemeister)
This release fixes a build issue that caused errors when using effect hooks.
- Add missing
_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 that as quick as possible :+1:
Bug Fixes
- Fix
setState
warning always being printed (#2057, thanks @marvinhagemeister)
Maintenance
- Queue
layoutEffects
in component render callbacks array (+0 B) (#2050, thanks @andrewiggins) - Separate
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.
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:
Features
- Add debug warnings when calling
setState
orforceUpdate
on an unmounted component (#2037, thanks @andrewiggins)
Bug Fixes
- Support re-suspending with
<Suspense>
(#2025, thanks @andrewiggins) - Add unpkg aliases (#2032, thanks @developit)
- Fix
ref
not always called inuseImperativeHandle
(#2021, thanks @JoviDeCroock)
Golf (size reductions)
- Inline
coerceToVNode
inside oftoChildArray
(-21 B) (#2040, thanks @andrewiggins) - Remove unused mount check in context Provider (-6 B) (#2039, thanks @andrewiggins)
- Golfed render (#2045, thanks @MohammedSheikhIbrahim)
- Remove useless return from eventProxy (#2026, thanks @jridgewell)
- Rewrite
useImperativeHandle
to useuseLayoutEffect
(-35 B) (#2003, thanks @andrewiggins) - Re-purpose
renderCallbacks
as a general per-component commit queue (#2011, thanks @andrewiggins)
Types
- Add
nonce
to JSXHTMLAttributes
types for better Content Security Policy support. (#2035, thanks @calvinf) - Remove internal import from compat types (#2018, thanks @andrewiggins)
- Fix internal
vnode
typings (#2015, thanks @pmkroeker)
Maintenance
- Remove end of line in
compat/mangle.json
(#2053, thanks @38elements) - Add
_afterPaintQueued
and_fallback
tomangle.json
(#2043, thanks @38elements) - Remove OpenCollective postinstall Banner (#2033, thanks @developit)
- Update
preact/compat
in readme (#2029, thanks @developit) - Fixed some typos and grammatical mistakes. (#2028, thanks @MohammedSheikhIbrahim)
- Add
_force
and_lastDomChild
tomangle.json
(#2023, thanks @developit) - Add
_suspensions
to mangle (#2019, thanks @JoviDeCroock) - Add npm script to run compat TS tests (#2017, thanks @andrewiggins)
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:
Bug Fixes
- Resolve attributes of reused nodes that weren't present in
virtual-dom
(#1987, thanks @JoviDeCroock) - Fix stale
context
values (forcreateContext
-API) (#2005, thanks @JoviDeCroock) - Properly flush nested
setState
callbacks (-6 B) (#2010, thanks @andrewiggins) - Import and re-export hooks explicitly to allow for webpack tree shaking (#2006, thanks @davidbailey00)
- Removing reference to
preact-context
library (#2001, thanks @jackbravo) - Fix
forceUpdate
enqueued child update being skipped (#1988, thanks @marvinhagemeister) - Append
Portal
node to container instead of prepend (#1971, thanks @toraora) - Always pull
_force
flag from component (#1984, thanks @marvinhagemeister) - Fix typos in JSDoc (#1973, thanks @polemius)
- Fix
replaceNode
not always taking effect (#1970, thanks @JoviDeCroock)
Types
- Remove
null
fromVNode.type
TS definition and add some TS tests (#1994, thanks @andrewiggins) - Add
_force
to internal.d.ts (#1990, thanks @38elements) - Improve
VNode
typings (#1979, thanks @andrewiggins)
Maintenance
- Golf
shouldComponentUpdate
(#1980, thanks @JoviDeCroock) - Add Songsterr to Real-World Apps section (#1972, thanks @followdarko)
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.
What's new?
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:
Fragments
componentDidCatch
preact/hooks
addonpreact/test-utils
addoncreateContext
APIcompat
moved to core- Plethora of compatibility fixes
- Many new warnings in
preact/debug
- Same 3 kB size as Preact 8
Again, we highly recommend checking out our new site and specifically the what's new section.
Changes since RC 4
Bug Fixes
- Rewrite
shouldComponentUpdate
handling to take more edge cases into account (#1931, thanks @JoviDeCroock) - Fix
UNSAFE_*
lifecycles being overwritten incompat
(#1946, thanks @marvinhagemeister) - Fix
PureComponent
rerendering when__source
changes (#1950, thanks @JoviDeCroock) - Fix default argument in
useState
not applied in rare cases (#1948, thanks @JoviDeCroock) - Change
.forceUpdate()
to participate in the update queue (#1939, thanks @developit) - Fix
vnode._children
should keep their type asarray
when diffing (#1924, thanks @cristianbote) - Allow numeric CSS values to be 0 (e.g.
opacity
) (#1927, thanks @JoviDeCroock) - Fix unnecessary rerender on equal contexts (#1925, thanks @JoviDeCroock)
Typings
- Add
disableRemotePlayback
to HTML Attributes (#1955, thanks @JoviDeCroock) - Add
volume
to HTML Attributes (#1938, thanks @jessicabyrne)
Maintenance
- Prevent mangling of
__source
and__self
(#1958, thanks @JoviDeCroock) - Add documentation on how to do releases (#1928, thanks @marvinhagemeister)
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.
Bug Fixes
- Avoid creating circular
children
refs increateElement
(#1917, thanks @JoviDeCroock)
Typings
- Fix PureComponent not passing generic types along (#1920, thanks @amelekhin)
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.
Preact Devtools are coming
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:
Features
- Add
isValidElement
to core (#1861, thanks @marvinhagemeister) - Throw error when passing plain objects as
children
(#1858, thanks @marvinhagemeister) - Add support for
form
attribute onbuttons
andinputs
(#1863, thanks @sventschui) - Warn when calling
setState
in aconstructor
(#1857, thanks @marvinhagemeister) - Implement support for async
act
callbacks and nested calls toact
(#1854, thanks @robertknight)
Bug Fixes
- Fix nested
setState
calls with accuratethis.state
(#1748, thanks @JoviDeCroock) - Fix
useImperativeHandle
handles after rendering (#1909, thanks @JoviDeCroock) - Fix
shouldComponentUpdate
leading to invalid DOM without children (#1888, thanks @JoviDeCroock) - Add
shouldComponentUpdate
check forcontext.Consumer
(#1901, thanks @cristianbote) - Fix
replaceNode
argument not always replacing node (#1900, thanks @JoviDeCroock) - Fix incorrect dom pointer with
shouldComponentUpdate
(#1871, thanks @marvinhagemeister) - Fix IE11 regressions (#1856, thanks @marvinhagemeister)
- Fix
undefined
styles not being cleared (#1853, thanks @marvinhagemeister) - Fix
act
not flushing effects/updates if global effect/update queues are non-empty beforeact
call (#1851, thanks @robertknight) - Support adding
refs
tomemo
'ed components (#1860, thanks @sventschui) - Tag
forwardRef
&memo
proxy components as React components (#1844, thanks @developit) - Fix IE11 not setting initial
select
value (#1838, thanks @marvinhagemeister) - Avoid accessing
fn.prototype
where possible (#1835, thanks @developit) - Only destroy DOM on first render (#1832, thanks @marvinhagemeister)
- Flatten children array as it is diffed (#1716, thanks @andrewiggins)
- Optimize creating array of childrens (#1743, thanks @Connormiha)
Typings
- Fix
compat
types (#1752, thanks @marvinhagemeister) - Add
key
to all jsx elements (#1887, thanks @marvinhagemeister) - Fix type definitions for
getDerivedStateFromProps
andgetDerivedStateFromError
(#1874, thanks @38elements) - Add
VNode.constructor
to internal type definitions (#1810, thanks @38elements)
Maintenance
- Add info message about react-devtools v4 (#1908, thanks @marvinhagemeister)
- Add back Code of Conduct from Preact 8 branch (#1897, thanks @marvinhagemeister)
- Make source files non-executable (#1894, thanks @jridgewell)
- Skip
form
attribute test on IE11 (#1868, thanks @marvinhagemeister) - Re-enable coveralls (#1867, thanks @marvinhagemeister)
- Disable coveralls until their outage is resolved (#1866, thanks @marvinhagemeister)
- Delete .flowconfig (#1855, thanks @38elements)
- Remove Flow type definition (#1846, thanks @38elements)
- Remove a duplicate test in render tests (and add additional child node checks) (#1847, thanks @OrKoN)
- Exclude Edge from running devtool tests (#1839, thanks @marvinhagemeister)
- Remove double build for TravisCI (#1837, thanks @cristianbote)
- Exclude devtools tests from coverage (#1808, thanks @marvinhagemeister)
- Fix test in IE by sorting attributes. (#1836, thanks @marvinhagemeister)
This release is a maintenance release and all users of the 8.x release line are encouraged to upgrade to it.
- Fix devtools bridge not working with react devtools v4 (#1876)
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.
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:
Features
- Diff
props
when replacing a node and don't diff whenhydrating
(#1786, thanks @JoviDeCroock)
Bug Fixes
- Fix
lazy
not forwardingrefs
(#1826, thanks @JoviDeCroock) - Fix Chrome Headless running on WSL (#1696, thanks @developit)
- Use internal reference for
hydration
flag (#1802, thanks @developit) - Fix
animation
andtransition
events handlers not being recognized (#1804, thanks @JoviDeCroock) - Fix IE11 incompatability with input type="range" (#1823, thanks @JoviDeCroock)
- Add additional test for
createPortal
-> normalvnode
(#1805, thanks @JoviDeCroock) - Fix
Portal
children always being mounted (#1781, thanks @marvinhagemeister) - Fix
debug
crash withhooks
import (#1773, thanks @JoviDeCroock)
Typings
- Add
Partial
tosetState
(#1779, thanks @pmkroeker)
Maintenance
- Fix typos across preact repository (#1796, thanks @kittenking)
- Fix typo (#1784, thanks @38elements)
- Upgrade
xvfb
config for Travis CI (#1822, thanks @prateekbh) - Add Web Maker to real world app list (#1762, thanks @chinchang)
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.
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.
8.x will be maintained further :wrench:
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.
Now You’re Thinking With Portals
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:
SSR Boost :speedboat:
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.
Rock solid ecosystem
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:
Features
- Add back support for string styles (#1744, thanks @marvinhagemeister)
Bug Fixes
- Add
requestAnimationFrame
fallback when tab is not focused (#1763, thanks @calebeby) - Move Code of Conduct into
.github
dir (#1765, thanks @developit) - Move
eslintignore
intopackage.json
(#1764, thanks @developit) - Fix various scenarios with
Portals
(#1749, thanks @JoviDeCroock) - Minor debug enhancements (#1755, thanks @marvinhagemeister)
- Bypass
props
during hydration (#1697, thanks @developit) - Fix uncontrolled inputs not changing
value
(#1760, thanks @JoviDeCroock) - Replace
catchRender
withcatchError
(#1742, thanks @andrewiggins) - Warn on invalid table DOM structure (#1745, thanks @JoviDeCroock)
- Fix
replaceNode
not unmounting when diffing twice withreplaceNode
a (#1723, thanks @JoviDeCroock) - Fix up
compat
types and tests (#1740, thanks @andrewiggins) - Golf sibling DOM handling (#1737, thanks @andrewiggins)
- Add return type to
_childDidSuspend
(#1735, thanks @pmkroeker) - Fix
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 :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:
Again, you are awesome
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:
Important
Because of the internal restructuring preact-render-to-string needs to be updated to at least version 5.0.4
.
Bug Fixes
- Restore debounceRendering after
act
(#1683, thanks @JoviDeCroock) - Fix cross browser assertions (#1708, thanks @marvinhagemeister)
- Bubble up Component dom changes up the virtual tree (+51 B) (#1700, thanks @andrewiggins)
- Begin rendering with
diff
instead ofdiffChildren
and other golf ⛳ (#1715, thanks @andrewiggins) - Implement
useRef
withuseState
(#1679, thanks @JoviDeCroock) - Fix
falsy
event values beeing added (#1712, thanks @cristianbote) - Minify names of externally exposed private functions (#1711, thanks @andrewiggins)
- Ensure correct unmount (#1687, thanks @JoviDeCroock)
- Correct
Portal
unmounting and props diffing (#1691, thanks @JoviDeCroock) - RFC: Privatize some options (-7 B) (#1692, thanks @andrewiggins)
- Begin
diff
with next DOM sibling inforceUpdate
(#1689, thanks @andrewiggins) - Replace
ancestorComponent
withvnode
parent pointer (+5 B) (#1688, thanks @andrewiggins) - Delete React debugging props
__self
and__source
(#1690, thanks @mxstbr) - Consistently use
_children
& combine Fragment and Component diffing (-73 B) (#1658, thanks @andrewiggins) - Don't use
typeof
check forh
(#1676, thanks @JoviDeCroock)
Typings
- Update compat typings (#1703, thanks @pmkroeker)
- Retype
style
to error onstrings
(#1675, thanks @pmkroeker)
Maintenance
- Update suspense so tests only rely on public API (#1724, thanks @andrewiggins)
- Disable Safari in Saucelabs tests (#1706, thanks @marvinhagemeister)
- Add redux to demo app (#1705, thanks @marvinhagemeister)
- Clean up scratch DOM after tests (#1701, thanks @andrewiggins)
- Separate lifecycle tests into separate files (#1702, thanks @andrewiggins)
- Add toEqualNode chai assertion (#1680, thanks @andrewiggins)
- Run ESLint on all source and test files (#1686, thanks @andrewiggins)
- Add
preact-charts
to Component Libraries (#1667, thanks @pmkroeker)
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:
The Suspense Is Real
@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:
The golfing continues :golf: :golfing_man:
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:
Faster hydration :zap: :checkered_flag:
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:
Removed string styles
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!
Preact Sightings :atom_symbol:
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!
Changelog
Features
- Introduce
Suspense
andlazy
(#1593, #1638 thanks @sventschui) - Don't read attributes during hydration (#1596, thanks @developit)
- Update README with the
proxx
demo (#1654, thanks @talentedandrew) - Make consistent use of key check logic (-12 B) (#1651, thanks @andrewiggins)
- Update links for the new preactjs org (#1649, thanks @JoviDeCroock)
- Support JSX-sourcemaps (#1628, thanks @JoviDeCroock)
- Simplify key matching technique (#1637, thanks @developit)
- Remove the unused
bundlesize
dependency (#1641, thanks @JoviDeCroock) - Add
travis-size-report
to the CI (#1633, thanks @wardpeet) - Revert the lookup on
documentView
since this introduced a regression (#1631, thanks @cristianbote) - Show
useEffect
warning instead of throwing error (#1623, thanks @yuqianma) - breaking: Remove support for style as string and other golfing (-32B) (#1606, thanks @cristianbote)
- Golf Hooks (-11B) and compat (-18B) (#1602, thanks @JoviDeCroock)
- Code golf
preact.js.gz
size down by 53 B ⛳️ (#1599, thanks @jviide) - Store text node's text content as
VNode.props
instead ofVNode.text
(#1600, thanks @jviide)
Bug fixes
- Update Fragment DOM log with
null
placeholder behavior (#1661, thanks @andrewiggins) - Prevent crash with nullish ref (#1657, thanks @JoviDeCroock)
- Remove
props.key
even whenkey === 0
orkey === ""
(#1607, thanks @jviide) - Fix unmount behavior when using
replaceNode
(#1647, thanks @JoviDeCroock) - Fix
react-hot-loader
compatibility by not checking onvnode
ref (#1644, thanks @JoviDeCroock) - Fix
this
reference incomponentWillUnmount
under contextConsumer
(#1627, thanks @sventschui) - Ignore
dangerouslySetInnerHTML
during hydration (#1595, thanks @developit) - Don't compare
vnodes
whenoldVNode
has nodom
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)- Only warn once about argumentless effects (#1625, thanks @JoviDeCroock)
- Warn about missing
preact-render-to-string
dependency (#1603, thanks @JoviDeCroock) - Insert portal children instead of overwriting the container (#1629, thanks @JoviDeCroock)
Typings
- Add types to
compat
(#1609, thanks @pmkroeker) - Add types for Suspense/lazy (#1619, 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 running a past alpha
or beta release of Preact X.
Code-Golf to the max :golf: :golfing_woman:
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:
Lazor sharp focus :telescope:
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.
Say hello to 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:
Easier hydration :heavy_check_mark:
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.
Loads of little fixes :wrench:
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:
- Reduce size by golfing down some pieces 🏌️♂️ (-39 B) (#1578, thanks @andrewiggins)
- Remove
focusElement
(#1548, thanks @JoviDeCroock) - Code golf diffChildren size down by 33 B ⛳️ (#1580, thanks @jviide)
- Prevent json injection (#1528, thanks @JoviDeCroock)
- Add
replaceNode
parameter torender()
(#1557, thanks @LukasBombach) - Add support for global event handlers like animation and transition (#1590, thanks @cristianbote)
- Add
styled-components
example (#1574, thanks @marvinhagemeister) - Add
useImperativeHandle
(#1556, thanks @JoviDeCroock) - Add
useDebugValue
hook (#1554, thanks @marvinhagemeister) - Warn about hooks outside render and/or components (#1509, thanks @JoviDeCroock)
- Improve nested effect rerenders in act (-49 B) (#1546, thanks @andrewiggins)
- Fix
_lastDomChild
disregarding placeholders (#1587, thanks @marvinhagemeister) - Fix useState can potentially add to the state queue and make the
_dirty
call neglect this (#1584, thanks @JoviDeCroock) - Fix infinite loop because of props mutation (#1577, thanks @marvinhagemeister)
- Fix Error boundary not applying in array cases (#1572, thanks @JoviDeCroock)
- Fix prevent crash when there is no last DOM child node (#1568, thanks @JoviDeCroock)
- Fix input value not in specified range (#1435, thanks @marvinhagemeister)
- Fix hoisting of components without DOM (#1559, thanks @marvinhagemeister)
- Fix wrong state references (#1465, thanks @mochiya98)
- Disable travis' email notifications (#1560, thanks @marvinhagemeister)
- Slight improvements to code coverage (#1558, thanks @marvinhagemeister)
- Run tests on MacOS 10.13 + Safari 11 (#1555, thanks @developit)
Typings
- Update type definition (#1581, thanks @38elements)
- Ts fixes (#1565, thanks @ForsakenHarmony)
- feat: adds microdata attrs types (#1585, thanks @Dangoo)
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 stable
The 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
Next-level conditional rendering
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!
Depth-based component updates
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:
Official adapter for enzyme
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
.
Status: Bundle size
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:
Bug Fixes
- Keep track of childDom between
diffChildren
calls (#1515, thanks @andrewiggins) - Remove getFirstOldDom (-42 B) (#1531, thanks @andrewiggins)
- Add support for arrays with holes as placeholders (#1440, thanks @marvinhagemeister)
- Apply state updates based on depth (#1534, thanks @JoviDeCroock)
- Fix incorrect depth ordering (#1536, thanks @marvinhagemeister)
- Fix nodes with different keys being reused (#1532, thanks @marvinhagemeister)
- Fix stale DOM with async preact-router (#1539, thanks @marvinhagemeister)
- Fix Portals not being unmounted (#1537, thanks @marvinhagemeister)
act
should be able to track and flush the full queue and all subsequent queues (#1520, thanks @JoviDeCroock)- Fix error with component attributes that start with
on
(#1530, thanks @JoviDeCroock) - Remove
prop-types
dependency (#1525, thanks @natevw) - Add clear button to demo logger (#1517, thanks @marvinhagemeister)
- Add
_depth
to mangle.json (#1542, thanks @38elements) - Remove unnecessary code (#1543, thanks @38elements)
Typings
- Use same type naming as @types/react (#1519, thanks @marvinhagemeister)
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:
Ghosting DOM elements :ghost:
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:
JSX Typings 💯
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:
Streamlined 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.
Community
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:
Features:
- warn about deprecated properties (#1511, thanks @JoviDeCroock)
Bug fixes:
- effect execution and cleanup order (#1501, thanks @JoviDeCroock)
_dom
beingnull
whenever sCU returnsfalse
(#1484, thanks @marvinhagemeister)- debug message should not throw for
undefined
andnull
(#1505, thanks @JoviDeCroock) - Remove unused component import (#1508, thanks @marvinhagemeister)
Typings:
- move JSX namespace into preact one (#1448, thanks @just-boris)
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:
Developer Experience Enhancements :hammer_and_wrench:
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:
- Warn on double encoding of JSX literals and other invalid nodes passed to
createElement/h
- Warn when an event handler is not a
function
- Warn when the container node passed to
render()
doesn't exist in the DOM - Warn on invalid dependencies passed to
useEffect/useLayoutEffect
Here is an example:
Other notable changes
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
).
What's next
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 🤫
You all are amazing!
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:
Features
- Add warnings for invalid
useEffect/useLayoutEffect
dependencies (#1495, thanks @JoviDeCroock) - Add warnings for
useMemo/useCallback
when dependencies haven't been specified (#1499, thanks @JoviDeCroock) - Add more
createElement
warnings in debug (#1494, thanks @marvinhagemeister) - Add warnings for
render()
(#1487, thanks @JoviDeCroock) - Add warning for invalid event handlers (#1409, thanks @JoviDeCroock)
- Add teardown to test-utils (#1458, thanks @JoviDeCroock)
- Add people demo from #1388 (#1453, thanks @andrewiggins @phaux)
- Add back
unstable_batchedUpdates
and replacemobx-preact
withmobx-react
in demo app (#1477, thanks @marvinhagemeister) - Add support for CSS Grid (#1407, thanks @JoviDeCroock)
- Switch from
*.mjs
->*.module.js
(#1425, thanks @marvinhagemeister) - Save 3 bytes (#1466, thanks @38elements)
- Add
teardown
totest-utils
(#1458, thanks @JoviDeCroock)
Bug Fixes
event.persist
should be a function, not an object (#1498, thanks @JoviDeCroock)- Fix Portal crashing devtools (#1491, thanks @marvinhagemeister)
- Fix stale DOM caused by empty Fragments (#1489, thanks @marvinhagemeister)
- Add test for fragment ordering (#1478, thanks @JoviDeCroock)
- Fix DOM removed before
componentWillUnmount
(#1471, thanks @marvinhagemeister) - Don't call
setState
callback or enqueue a render in constructor (#1454, thanks @JoviDeCroock) - Jump to the next childDom if its
_dom
isnull
(#1452, thanks @Almo7aya) - Apply compat normalisation for every
vnode
(#1450, thanks @JoviDeCroock) - Fix changes in getDerivedStateFromProps is not reflected to
_nextState
(#1446, thanks @mochiya98) - Fix missing mangle config for
_prevState
(#1442, thanks @mochiya98) - Always diff checked/value properties against the DOM. Fixes #1324. (#1438, thanks @utkarshkukreti) 🎉
- Add missing
test-utils
export inpreact/compat
(#1436, thanks @JoviDeCroock) - Replace
Object.assign
with custom assign function (#1433, thanks @marvinhagemeister) - Don't iterate over old CSS string (#1429, thanks @marvinhagemeister)
- Fix safari failing on calc with CSS Custom Properties in SauceLabs (#1428, thanks @marvinhagemeister)
- Don't append
px
suffix for CSS Custom Properties (#1426, thanks @marvinhagemeister) - Updated links to the funcy.js source. (#1420, thanks @michael-klein)
- Fix
componentDidUpdate
arguments (#1455, thanks @38elements) - Fix
tagName
prop trying to change element type (#1419, thanks @JoviDeCroock) - Fix missing className normalization on hydrate (#1421, thanks @marvinhagemeister)
- Fix inconsistencies in
act
(#1437, thanks @JoviDeCroock) - Always diff checked/value properties against the DOM. (#1438, thanks @utkarshkukreti)
- Render bailout on equal state transition (#1449, thanks @JoviDeCroock)
- support svg attributes (#1451, thanks @JoviDeCroock)
- Move context update logic to diffing (#1468, thanks @JoviDeCroock)
- Fix remove button adding todos in demo app (#1488, thanks @marvinhagemeister)
Typings
- Update option types (#1493, thanks @JoviDeCroock)
- Update internal compat types (#1483, #1456, thanks @38elements)
- Update internal context types (#1432, thanks @38elements)
- Update Component in internal.d.ts (#1443, thanks @38elements)
- Fix
vnode
type definition (#1447, thanks @38elements) - Remove unnecessary settings in tsconfig.json (#1457, thanks @38elements)
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 🎉
Introducing preact/test-utils
With 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.
Bug-Fixes
- Fix devtools not loading (#1360, thanks @calebeby)
- Inline vnode children (#1317, thanks @developit)
- Remove double Promise on initialization (#1370, thanks @bmeurer and @marvinhagemeister)
- Fix camelCase
style
properties not working (#1375, thanks @mochiya98) - Fix
Portal
rendering undefined tags into the DOM (#1367, thanks @marvinhagemeister) - Fix
this.props
not set forPureComponent
components (#1384, thanks @marvinhagemeister) - Use
console.error
for caught errors in the devtools adapter (#1385, thanks @yuqianma) - Fix state not updated when
setState
is called incomponentWillReceiveProps
(#1369, thanks @mochiya98) - Fix svg
foreignObject
not being treated as svg (#1391, thanks @marvinhagemeister) - Fix
onBeforeInput
not attaching event handler (#1366, thanks @marvinhagemeister) - Fix
React.isValidElement
check failing forvnodes
created with Preact (#1380, thanks @marvinhagemeister) - Fix
<select>.value
not working (#1397, thanks @JoviDeCroock) - Fix multiple selections for
<select>
only selecting last item (#1405, thanks @JoviDeCroock) - Fix
force
flag blocking state update in secondrender()
(#1377, thanks @developit) - Fix IE11 crashing because of missing
Element.prototype.remove
(#1395, thanks @marvinhagemeister) - Fix
forwardRef
andmemo
ignoring refs when composed together (#1358, thanks @marvinhagemeister)
Performance
- Move
_prevState
for devtools out of core (#1379, thanks @developit) - Reuse
oldChildrenLength
to save bytes (#1386, thanks @yuqianma) - Don't call
setProperty
for style strings (#1394, thanks @choumx)
Other
- Fix unable to satisfy type parameters for
static
methods (#1365, thanks @marvinhagemeister) - Add back missing camelCase attributes (#1390, thanks @marvinhagemeister)
- Add missing autocorrect attribute types (#1393, thanks @garybernhardt)
- Ignore final new line for all
mangle.json
files (#1378, thanks @developit) - Add more tests for
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 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 🚀
- Switch away from
MessageChannel
tosetTimeout + requestAnimationFrame
🎉 (#1346, thanks @cristianbote) - Fix lifecycle order of
componentWillReceiveProps
in relation toshouldComponentUpdate
💯(#1348, thanks @mochiya98) - Fix incorrect operator precedence in
memo()
🎉 (#1347, thanks again @mochiya98) - Preserve devtools global hook 🔧 (#1333, thanks @developit)
- Fix missing
server.js
in npm package (#1332, thanks @developit) - Fix incorrect
this
binding insetState
callback (#1344, thanks @marvinhagemeister) - Fix stale
props
andstate
reference whenshouldComponentUpdate
returnsfalse
(#1351, thanks @marvinhagemeister) - Don't leak
Text
nodes out oftoChildArray
(#1357, thanks @developit) - Add missing consistent mangle name for
_parentDOM
(#1320, thanks @andrewiggins) - Add
hgroup
to TypeScript typings (#1340, thanks @ForsakenHarmony) - Add missing
isReactComponent
-property inpreact/compat
(#1337, thanks @marvinhagemeister) - Downgrade IE11 to run on Windows 7 in Saucelabs (#1319, thanks @marvinhagemeister)
Preact X Alpha 0 is here!
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 ✅
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
.
componentDidCatch ✅
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 />;
}
}
Hooks
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);
createContext ✅
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>;
}
CSS Custom Properties ✅
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>;
}
Devtools Adapter
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 👍
Compat lives now in core
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";
New compat features
forwardRef
UNSTABLE_*
-Lifecycle hooksmemo
Removing old React APIs
To 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.
Breaking Changes
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.
The VNode
shape has changed
We renamed/moved the following properties:
attributes
->props
nodeName
->type
children
->props.children
The 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 synchronously
In 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 changed
The 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/debug
Our 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.
Better support for Tree-Shaking
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.
Other breaking changes
- Falsy attributes values are no longer removed from the DOM. For some
attributes (e.g.spellcheck
) the valuesfalse
and''
have different
meaning so being able to renderfalse
is important - The
Component
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 called - A falsy argument passed to
setState
will not enqueue an update. This change was made to support returningnull
from theupdater
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 objectsetState({})
. - The toplevel
rerender
export has been removed.
Minor Changes
render(null, container)
no longer renders an empty text node but instead renders nothing- We longer support a synchronous
options.debounceRendering
. The value ofoptions.debounceRendering
must asynchronously invoke the passed in callback. It is important that contributors to Preact can consistently reason about what calls tosetState
, etc. do, and when their effects will be applied. See the links below for some
further reading on designing asynchronous APIs.
Known Issues
- Nested
Fragments
lead to more DOM operations than necessary - Hooks state not visible inside the
devtools
panel
- Fix a bug in
8.4
where nestedpreact.render()
calls would cause an infinite loop when flushing the mount queue. (#1269, thanks @pl12133!)
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 👍
- Perf: Improve adding and removing large trees 🎉 (#1211, thanks @lowaa)
- Drain render queue in a single micro task 🎉 (#1135, thanks @rpetrich)
- Fix missing build when installing from git (#1251, thanks @garybernhardt)
- Fix invalid
ref
invocation (#1235, thanks @developit) - Fix
cloneElement
test (#982, thanks @decadef20) - Reorganize and improve render unit tests (#1199, thanks @andrewiggins)
- Improve
componentDidUpdate
tests (#1198, thanks @andrewiggins)
TypeScript Improvements!
- Add
onInvalid
form event (#1221, thanks @namankheterpal) - Fix
h()
overloads (#1246, #1214, thanks @gpoit, @garybernhardt) - Fix
AnyCompoent
type (#1249, thanks @scurker) - Use proper type for
key
(#1248, thanks @wojtczal) - Add
boolean
as a component child (#1219, thanks @KasparEtter) - Add
onError
image event (#1209, thanks @jackmoore) - Add support for
defaultProps
(#1181, thanks @Alexendoo) - Fix
cloneElement
definition (#1197, thanks @hiddedejong)
Flow improvements!
- Fix typings for
[email protected]
(#1230, thanks @ngyikp) - Refine
options
flow type (#1204, thanks @reyronald)
README Improvements!
- Add Ultimate-Guitar (#1244, thanks @JiLiZART)
- Add logo to README (#1243, thanks @reviewher)
- Add section for
[email protected]
(#1212, thanks @38elements) - Remove duplicate project (#1192, thanks @stephenmathieson)
- Fixes an issue in
8.3.0
whereprevState
(as passed to componentDidUpdate) pointed to the wrong interim state value when batching (#1186, thanks @carlhopf!) - TypeScript: Added ShadowRoot and DocumentFragment as parent option to render (thanks @cromefire!)
New Features!
🙌 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!
Improvements
- We're shipping
.mjs
now! (#1165, thanks @mathiasbynens for the nudge) - Fix an issue where
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!)- Some code golfing to offset the new lifecycle methods (#1122, thanks @andrewiggins, @marvinhagemeister)
- A little perf/size tweak for render callbacks (#1113, thanks @valotas)
- Someone found dead code in Preact! awesome. (#890, thanks @MrErHu & @clarkdo)
- We've dropped IE9 and IE10 from our SauceLabs tests (thanks @mkxml!)
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!
TypeScript Improvements!
- Add support for specifying the types of a component's children (#1116, thanks @Alexendoo)
- Add
on*Capture
event handler attributes and PointerEvents to the TS definitions (#1101 #1102, thanks @jakearchibald) - Improve render()'s return type (#1085, thanks @valotas)
- Add
controlsList
attribute for media elements (#1134, thanks @wayou)
This release fixes an issue with our minification pipeline, which incorrectly mangled export declarations.
- Don't mangle module exports #1077, thanks @marvinhagemeister
- [ts] Add missing
ref
andkey
attribute #1051, thanks @andrewiggins - [ts] Add default parameter for Generic argument of
VNode
#1082, thanks @andrewiggins - [ts] Remove devtools module declaraction #1083, thanks @andrewiggins
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:
- [ts] Rewrite TypeScript defninitions and add support for strict mode
- #1071, thanks @levrik
- #1044 #1033 #1026, thanks @marvinhagemeister
- #1037, thanks @k1r0s
- #1027, thanks @wuweiweiwu
- #869, thanks @niedzielski
- #737, thanks @valotas
- #695, thanks @jmrog
- #1015, thanks @ovr
- #1005, thanks @jrf0110
- #1003, thanks @programbo
- #990, thanks @timurista
- #933, thanks @scurker
- #943, thanks @andybons
- Fix HMR sometimes throwing with
preact-router
#988, thanks @developit
- Fix
preact/debug
failing to load in Webpack 3 + ES Modules (#924 #935, thanks @whitetrefoil) - Added null to paren union type of render (#937, thanks @nickytonline)
- [debug]: Warn when passing incorrect arguments to
render()
(#885, thanks @markselby9) - [ts]: stateful component should be assignable to
AnyComponent
(#905, thanks @mike-north) - [ts]: add link preload "as" to
HTMLAttributes
type definition (#907, thanks @niedzielski) - [flow]: Fix flow types and render method issue (#868, thanks @sgrowe)
This release makes some tweaks to the newly released preact/debug
.
- Enhanced errors for
preact/debug
- Fixed issue where key warnings could be shown for components without keys
8.2.2 fixes a bunch of little issues encountered by those upgrading to 8.2.1 👍
- Use explicit import paths in
src
for ES Modules compatibility (#792, thanks @slaskis) - Fix CLI donation message failing if
npm
is unavailable (#804, thanks @andrejsm) - Fix Babel attempting to use Preact's configuration (#825, thanks @rubenmoya)
- Fix invalid sourcemap by updating Rollup (#800)
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 whenpreact-compat
was not present
- 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!- Switch back to microtasks (via
Promise#then
) for async! (#708) - Fix unnecessary child reordering for certain cases (#717 - thanks @windyGex & @e1ectronic)
- Fix attributes not being removed when diffing against SSR'd DOM (#677, @dmail)
- Fixed Boolean and Number component render return values rendering
<undefined>
(#671, @dharFr) - Typescript Definition Improvements (#634, #641, #669, #730, #740)
- Optimizations (#672, #696, #697)
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.
- Remove object check before setting attributes (fixes custom toString, #401 - thanks @NekR!)
- Cast boolean children to null for component props (fixes rc-animate, #629 - thanks @hassanbazzi!)
- Call
componentDidMount
on children beforecomponentDidUpdate
on parent (#440, #506 - thanks @robertknight!) - Revert 8.0.0 behavior of throwing when encountering undefined components (#627)
preact/debug
will be released shortly and does a much better job reporting stack traces!
🌈 Also worth noting, the linkstate module is now available.
Quick follow-up to 8.0.0
- fixes an issue with
preact-router
(thanks @lukeed & @kbaxter!) - Fixes element removal regression in old IE (#625)
8.0.0 (beta)
It's here! 🌈
This release represents a huge step forward for Preact:
- Significantly increased performance - in some cases by 30%.
- Better compatibility -
key
for PFC's,class
integrations, capturing events. - Fewer edge cases - goodbye to unnecessary mounts and DOM hierarchy errors.
- Even smaller - Preact had been 3.9kb for a while - now it's 3.3kb (and headed for 2.9kb!)
💁 If you're looking to upgrade, be sure to read the quick guide.
Breaking Changes
- Pure Functional Components now have backing instances. This means
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
andclassName
no longer serialize Object values to Strings. Instead, use classnames (#401)preact/aliases
is no longer necessary.createElement()
is now an alias ofh()
right out of the box!- DOM element recycling has been removed. It was a source of issues for many, and is no longer necessary for great performance thanks to diff optimizations that reduce the number of cases where elements are removed and re-added. (#544, #351, #461, #459, #503, #535, #562)
- Undefined components references now throw rather than rendering
<undefined>
(#574) - No more
Symbol
. Instead of try to useSymbol.for('preactattr')
,__preactattr_
is always used. - Render debouncing now uses
setTimeout(0)
instead of Promises. It's smaller, doesn't swallow rendering errors in Safari, and was already the fallback (#357) - The non-standard
componentDidUnmount()
lifecycle method is removed. UsecomponentWillUnmount()
. onXxxxCapture
is now supported for registering capturing event handlers.- Events like
focus
andblur
are no longer automatically capturing by default.
Bugs Fixed
- Hierarchy errors are a thing of the past (thanks to recycler and PFC rewrites) (#380, #391)
- Fixed edge case that could cause children to be rendered out of order (#581, #603)
- Unmount lifecycle is always fired when replacing a Component with an empty element (#538, #534)
ref
functions attached to DOM nodes are no longer invoked for updates, only for mount/unmount.
Other Notable Changes
- "holes" in JSX children are now preserved and used intelligently by the diff (#580, #540)
- Re-rendering a compositional child with a different
key
prop now triggers a remount (#338) - JSX children passed to a Component are preserved rather than normalized (#551)
- Preact no longer relies on the
Text
orArray
constructors for type checks, instead relying on duck typing (#595, #530) - Ignore whitespace-only Text nodes during SSR hydration. SSR boot is now significantly faster than cold boot.
Here's the list of changes itemized by commit:
https://github.com/developit/preact/compare/master...8
Just a small bugfix release - DevTools was throwing an exception if components didn't inherit from Component
. Preact supports components not inheriting from Component
, so we've fixed the DevTools to match 👍
⚛️ Preact 7.2.0 is now available as a regular release!
npm install --save preact
Bugs Squashed
- Fix IE issues from 7.1 and update test cases (huge thanks to @mkxml for the hard work on this 🙇)
- Fix TextNode duplication in IE (#430, thanks also to @mkxml)
- Fix unnececssary diff when swapping from
dangerouslySetInnerHTML
tochildren
(thanks @harish2704) - Fix issue in 7.x with
<select>
sometimes not applyingvalue
prop (#446) - Don't stringify
true
children, instead skip them (#468, thanks @jxodwyer) - Fix issue where unmount could be skipped on a top-level component (#493, discovered by @insin)
- (DevTools Integration) Fix multiple root element issue
New Features
- Use a shared empty Array for
props.children
when there are no children. Fixes simple shallow equality-basedshouldComponentUpdate
for leaf nodes 🎉 - Remove
instanceof SVGElement
check in favor of duck typing. Fixes JSDOM compatibility and improves diff performance (#423, thanks @nhunzaker) - Better TypeScript Definitions: Component lifecycle methods, setState callback, etc
- 10x performance boost for initial rendering (#416)
- Fix edge case when swapping component root (#414)
- Fix diff reflow when removing leading element (#394)
- Check existence of firstChild before checking if it is a Text node
- Performance optimization for element/tree removal
- Re-add short-circuit for PFC's (fixes compositional PFC triggering constant recycling)
- Fixed TypeScript definition signature for linkState (#427)
- Add a whole bunch of explanatory comments to the diff engine 🎉
Bugfix
This release fixes an issue when hydrating from a static server-rendered DOM that could cause Preact to do far more work than it should have been doing. If you're doing SSR, check out this release for a massive performance boost.
7.x
7.x is currently in beta. It should be an entirely safe upgrade for most.
The reason it's a new major version is because Preact now ignores externally created DOM elements when rendering, unless performing hydration from a server-render (ie - the diff is initiated from a render()
against an element that was not created by the DOM renderer).
Features
- Preliminary React DevTools support thanks to the amazing @robertknight! 🙇
Fixes
- Prevent against reassignment of the same value to TextNodes in Firefox (#368, thanks @zbinlin)
- When swapping the base of a composed child component, update its parent's base reference (#349)
- Prevent accidental duplicate recycling of elements when swapping a component's root element (#373, thanks @jakearchibald)
With 6.3.0
, the children
prop (on a VNode) is now always an Array, even if there are no children. This allows us to skip an existence check when plucking children within render:
// 6.2.1 & prior:
({ children }) => children && children[0];
// As of 6.3.0:
({ children }) => children[0];
This change is backwards compatible since previously an empty array was already being returned for no children in some cases. Now it's just more consistent! 🌈
Bugfix: Switch to using the render parent to determine if re-rendering starting from within an SVG, since the current element may not exist (eg: for a component).
Improvements
- Support for infinitely nested
children
! - Massive performance boost for
h()
(the hyperscript/jsx processor/reviver). - Tons of little performance optimizations
- Allow components to not inherit from Component without caring
- Add
aliases.js
andtypings.json
to the NPM package.
Public Changes
- Rename
Component._disableRendering
toComponent._disable
to save a few bytes - Removed undocumented support for
getInitialState()
on classful components.
This has never been part of the API but was left in core in order to support
preact-compat
's use. It is now being moved intopreact-compat
. This allows preact to normalize class components that don't inherit from Component.
Bugfixes
- Fix regression in
6.1.0
where state changes incomponentDidUpdate()
resulted in synchronous re-renders - Fix issue where rendering an SVG element using the
className
prop (alias) would incorrectly assignclassName
as an attribute. /cc @pl12133 - Fix serializing
class
for SVG (test included) (#334)
- Tons of little optimizations!
- Don't skip empty values in
extend()
(and thus insetState()
). Fixes #308. - Address ownership issue when rendering using reclaimed DOM. Fixes #297.
- Fix issue where re-rendering an intermediary high order component could remove (or fail to add) the associated element.
- When removing old props from the DOM, skip those with empty values.
- Exclusively rely on DOM state when diffing
value
andchecked
props. Fixes #326. - Use strict equality when comparing attribute values against prop values. Fixes #327.
- Upon initial entry into diff, check if the diff should start out in SVG mode. Fixes #331.
- Fix prop cache reset triggering in the wrong case (affected performance)
- Add typings path to
package.json
. Fixes #318. - Add support for single level of array children in h() (#313)
- Move both
className
toclass
normalization and hashedclass
stringification out ofh()
and into the DOM renderer.- Tiny possible breakage here: if you were creating VNodes using
className
and expecting them to haveattributes.class
instead ofattributes.className
, that is no longer the case.
- Tiny possible breakage here: if you were creating VNodes using
- Fix
<input list="id">
when datalist element is placed after the input in the DOM (Issue #294, thanks @vutran!) - Fix HMR issue caused by recycling of a re-used Component base. (Issue #295, thanks @katopz!)
npm install --save [email protected]
Features
- Add support for SVG
<foreignObject>
(#278, thanks @amio!) - Add
preact/aliases
import: A copy of preact that includes acreateElement()
alias (#168/#274, thanks @ngasull!) - Switch to use event capturing for increased consistency with React (#266/#271, thanks @i-like-robots!)
Breaking Changes
- Discard
keyed
nodes when diffing children instead of allowing them to be reused unkeyed linkState()
no longer falls back to components path lookups and no longer auto-invokes functions- These features were unused & poorly documented, and added extra weight
- Remove default empty
options.vnode
hook- While this is technically a breaking change, very few people use this API
- Simply perform an existence check on the previous hook prior to calling it
Bug Fixes
- Fix and tests for regression in
5.7
that could cause nodes to be removed (related to #260/#277) - Fix initial render failing to reuse certain components when picking up from SSR (#260)
- When swapping between Text, Comment and Element nodes, recycle whole orphaned trees
- Prevent the recycler from collecting non-Element nodes 🐛
- Switch back to the pre-5.7 case-sensitive
on
prefix for event handler props (#275, thanks @c2h5oh!)
- Correct regression introduced in
5.6.0
where re-rendering components with the same root node could duplicate their DOM. Fixes #257. - Enforce
this.props
andthis.context
, even when a class improperly inherits fromComponent
(eg: callssuper()
without forwarding arguments) - Fix for all empty vnodes (
""
,null
, etc) rendering a comment - this should only occur when an empty vnode is returned from a component'srender()
. - Make event handler "on" prefix case-insensitive
Features
- When rendering
null
, a comment node will be inserted instead of an empty TextNode. - When using
linkState()
with components instead of DOM elements, use the first argument passed to the event handler as the default value unless a path is given.
Bug Fixes
- Fix case where switching from a String to Object style value would attempt to assign numeric CSS properties to the element (#233)
- Fix bug where using all lowercase event names would skip bypass binding implementation (but still mostly work)
- Fix and test for double-nulling of refs when changing the type of a component's root DOM element (#243)
- Fix IE bug caused by assigning to the
nodeValue
property of a TextNode that has been removed from the DOM.
Features
- #237 Imporving performance by inlining hook calls (thanks @trashhalo!)
- Disable rendering on unmount (thanks @Madumo!) [discussion]
Bug Fixes
- Fix keyed node removal issue noted by @localvoid and originally noticed by @kruczy in #235.
🎉 Preact 5 is here! 🎈
Version 5 represents a fairly major jump forward. It should be backwards-compatible, but major version increment is to signify a few new features that will not be made available in older versions - mainly built-in SVG support, and async rendering.
Take a few seconds and upgrade, you'll be happy you did! 🌈
Tip: If you're using preact-compat, it's best to upgrade that to
2.0.0
at the same time. Since Preact 5+ now includes built-in support for SVG,[email protected]
drops thepreact-svg
dependency, saving you around1.7kb
.
Along with the lovely stable
stamp, this release includes some finishing touches:
Bug Fixes
- Fix case where a
ref
may be nulled before a component is unmounted (#232, thanks @slmgc!) - Ensure remounting component trees invokes mount lifecycle events for deeply nested children (thanks to @kruczy @madumo et al for their help with this!)
New Features
-
Style objects now have a lightning fast pipeline out to the DOM. (#228, thanks @trashhalo!)
Example:
<div style={{ foo:'bar '}} />
now diffs against the current style rather than stringifying the object
- Fixed lifecycle event DOM timing! #65 and #96
- Fixed swapping issue #230
Features
- #220 - Add Flow definition (fixes #219) - thanks @bouk!
Bug Fixes
- #218 - Fix nested JSX text children resulting in multiple TextNodes (thanks @bardt!)
Minor Changes
-
Fix an inconsistency with how
defaultProps
are applied (developit/preact-compat#47)A key in
props
with a value ofundefined
should be treated as a missing key, and the value fromdefaultProps
should be used in its place. -
Switch
setImmediate
backend fromMessageChannel
toPromise#then
(change diff)This is much faster!
However: This comes with the caveat of being unusable for animation. While this matches the use-case for
setImmediate()
within Preact (debouncing rendering), it means thatcomponentDidUpdate()
andsetState()
callbacks should not be used as a means of animation. ** This is only true when using the built-in debounce mechanism. Overriding to requestAnimationFrame is still a great way to do animations via these hooks.
Bug Fixes
-
Fix an issue where swapping between functional and classful children of a high-order component could trigger an unmount in certain cases
💁 If you're using preact-router, this fixes a redirect breakage
- #207 Fix
xlinkHref
prop for<svg>
tags - thanks @aeosynth!
Bugfixes
- Ignore
props.children
ifchildren
are manually specified (as jsx children, or the third argument toh()
) - Fix and test for the
<svg class>
bug @zhenkunou found and reported in #202 - Tiny size optimizations to offset the cost of the above fix :)
- Fix and (corrected) test for object style attribute serialization (#204) - thanks @katopz
- 🎨 Add built-in support for inline SVG! (#202)
Bugfixes
- Fix issue where
value
and a few other properties could get out of sync with their DOM counterparts. - Fix overly optimistic codemod that was breaking child resolution in
5.0.1-beta.14
. The codemod is now more intelligent and will only remove pointless initialization toundefined
if not done within a conditionally executable block.
- Fixes
5.0.1-beta.13
having been published without the beta flag.
- Bugfix: When recycling old trees due to a Component render producing a different root node, avoid accidentally recycling the
base
of a high-order child component.
Bug Fixes
- Fix issue where switching HOC child components could trigger unmount lifecycle methods on the parent
Bug Fixes
- Fix issue where Components rendering
null
would break functional root check introduced in5.0.0-beta9
(#182) - Fix clearing a previously
null
/undefined
value when usingclassName
compat alias (#181)
New Features
- Allow functions as VNode children (#154)
This is used in libraries that provide animation functionality by re-rendering function children with changing props:
render() { return ( <SomeAnimator start={0} end={155} loop> { hue => ( <span style={{ color: `hsl(${hue}, 100%, 60%)` }}>Rainbow</span> ) } </SomeAnimator> ); }
Bug Fixes
- Account for High-Order stateful child components wrapped in one or more functional components (#175)
- Fix disappearing element issue when swapping component root between Element and Text nodes (#176)
- Verify nesting ownership when attempting to unmount High-Order components
Other
- Various performance and memory optimizations
New Features
- Add support for
cloneElement()
. See React's Docs for more.
Bug Fixes
- Wrap DOM property assignment in a
try{}
block, as it can throw. - Fix element reordering regression (#174)
Potentially Breaking Changes
- Switch to exclusively named exports. Fixes compatibility with ES Module bundlers like Rollup (#150).
Bug Fixes
- Don't invoke
shouldComponentUpdate()
when updating viaforceUpdate()
(#158) - Fix diff self-correction issue that resulted in an unnecessary element removal and re-append (#159)
Potentially Breaking Changes
- DOM event handlers are no longer invoked with the source element as their context (
this
) (#153) - Adding properties to context within a tree no longer overwrites, instead it extends/appends (#156)
Bug Fixes
- Fix for high-order component mount lifecycle (#143)
- Fix incorrect rendering of
0
values (#149)
Features
- Add
key
property to VNodes (#155)
Optimization
Preact 4:
Preact 5:
-
Fix
children
being ignored when passed explicitly via props in certain cases. Fixes developit/preact-compat#44 (thanks @ld0rman!)Fun fact: this means you can now do:
<div children={['hello!']} />
- Bugfix: Fixes an issue caught by preact-compat's ref tests, where swapping the root node rendered by a component would null its ref twice.
- Fix regression in 4.6.2 related to recycled component DOM not being treated as first render
- A few small optimizations
-
Merge #106: removes some unnecessary code, drops ~50 bytes
-
Lazy-instantiate the internal mapping for
linkState()
and setState's callback queue.This reduces allocation cost for components. It also reduces overall memory consumption for classful components that don't make use of those given features (certainly the common case for
setState
callback)
- Don't attempt to append a child to a parentNode if the child is the parentNode. Fixes Issue #126.
-
Optimize serialization of Objects to CSS strings to be about 5x faster (benchmark: https://esbench.com/bench/570daee0db965b9a009659f7)
-
Rethink solution to #120. TL;DR: fresh instances, cached DOM. Long version:
Re-invoking the constructor on a class was not a great idea. Babel's transpiled constructors
(and basically anything else) re-assign to the prototype, which is slow and a fairly bad idea.
Also, and more importantly, it was assigningthis.base
tonull
, completely ignoring the
main reason for caching components (caching their generated DOM using the component itself
as a cache key). This commit changes the behavior to discard the cached component instance
itself, re-using only the base by copying it to a fresh instance. Best of both worlds!
- Fix for #122: don't assume Function.prototype exists, as it does not for Arrow Functions (thanks @LinusU!)
- Fix regression since
4.5.0
wherekey
tracking for components would fail in some cases, causing components not to be recycled. Relates to #98 and the second issue noted in #120. - Switch to a global/named symbol
Symbol.for('preactattr')
for the prop cache key (still falling back to__preactattr_
). - Address the state re-use issue noted in Issue #120 by manually re-invoking component constructors when re-using components from the recycler.
Bug Fixes
- Fix context being null/undefined when unset. It should be an empty object.
- Fix issue where
ref
(andkey
) were not being removed fromprops
prior to being passed into component render (Issue #98)
Optimizations
- Drop unnecessary cloning of props/context
- Ship a more optimized default build by applying
uglify-js
without name mangling and with beautification (removes comments and applies dead code elimination)
Bug Fixes
- When reclaiming externally created elements (such as via
dangerouslySetInnerHTML
), copy their attributes into the prop cache so they are properly diffed on subsequent render (Issue #97) - Fix cached unmount behavior: lifecycle events should be invoked for nested components, but only the top-level component should be physically removed from the DOM. The rest remain cached within that component's DOM + VDOM tree (Issue #94)
- Fixed issue where setting the
value
prop for a<select>
element could have no effect on initial render
- Fix an issue where invoking refs may be skipped during unmount (ex: re-render swaps high-order components)
- Fix a few cases where refs were invoked with the wrong value (Issue #87, thanks @chrisdavies)
Preact now explicitly removes falsey (false
, null
and undefined
) properties and attributes from the DOM. This behaviour is consistent with React's. See #83 and #58.
This is purely a bug fix release, so be sure to update if you're using Preact 4.x.
Bugs Fixed:
- Fix orphaned keyed VNodes not being removed in certain cases, such as when there are adjacent non-orphaned non-keyed VNodes (see developit/preact-compat#21)
- When diffing a component against a non-component VNode, if the component render returns a different DOM node, make sure to reclaim the original node. (Issue #73)
- Preact 4 is now officially out of beta. Please still report any bugs you find!
- setState() callbacks should be called with the component as their context.
- Fix multiple camelCase'd CSS properties (#66)
- Fix child component refs not being invoked with
null
when the associated component is unmounted - Fix high order component refs linking to parent component when they should link to the child component/node.
- Cancel preliminary support for String
refs
. Preact core will only be supporting function refs, since String refs are "mostly" deprecated.
- Add support for
refs
! - Add support for
defaultProps
(static property on Components) - Possibly Breaking Change: cache rendered DOM with components when recycling
- Possibly Breaking Change: don't wipe recycled DOM nodes, simply diff when re-used
- Use
setImmediate()
to improvesetState()
performance where available - Skip empty values when serializing
style
objects - Coerce falsey
className
andstyle
values to an empty string to avoidclass="null"
andstyle="null"
- Rename missing component insert from
<x-undefined-element>
to<undefined>
- Use a
Symbol
for storing the prop cache where available
- Performance tuning for a ~10% improvement on DBMonster (basically 10% faster diff algorithm)
- Refactored diff algorithm to be easier to follow
- Add
Component.prototype.forceUpdate()
method. - Fix a bug where a child component of a high-order component self-rendering (eg: via
setState()
) would cause a subsequent re-render of the parent component to re-initialize itself and the child (through the recycler, but this was causing thrash). - Fix an issue where nested components would not receive unmount lifecycle hooks (fixes Issue #47)
- Bugfix: pass
context
through recycled constructors (with thisreact-redux
is now fully supported!) linkState()
when used with top-level keys (ie, not dot-notated) will no longer mutatethis.state
in-place.(Nested keys can and will still mutate this.state, since the implementation of immutable state traversal would essentially be a small immutability library, not something Preact core can justify)
This is likely the last beta release of Preact 3.0, it'll become the stable branch shortly.
Feedback and testing welcome!
- Use a safeguard method to obtain preact attr cache objects before writes
- Fix edge case where fallthrough attribute values would not be stored in the preact attr cache
null
instead ofdelete
for_component
refs, avoiding shape mutations- build tweaks
- Preact's codebase has been factored into modules
- Reduced possible repaints by collecting property cache into a namespace
- 10-20% performance improvement under heavy rendering load!
- Now available in npm under a nice
dist-tag
:npm install [email protected]
- Fixes for event removal (#34), tests.
Beta version of the 3.0.0 major bump:
3.0.0
- Added
context
support - Bugfix:
componentDidUpdate()
should not be called after initial render - Switch from tracking
nextState
to trackingprevState
- Drop
VNode#__isVNode
in favor ofinstanceof
(reason)
- Performance improvements for asymmetric DOM properties
- Account for external mutation of properties
- Fix: ensure the npm package includes
src/
since it's now used by anyone usingrollup
for bundling (viajsnext:main
).
- Switch to a rollup-powered build, courtesty of @sheepsteak (thanks!)
- Apply more strict linting around the codebase, removed some unused code. General cleanliness += 1.
- Fix incorrect behavior where attributes with explicit
false
values were being skipped. - Readme updates as ever.
- Fix detachment of content attributes by preferring their property equivalents where available
- Preact 2.0.0 adds support for High-Order Components (yay!)
- Redues the filesize by ~300b