React team just announced new React Hooks API, and I think it will be a worthy addition to Preact.
The RFC: https://github.com/reactjs/rfcs/pull/68
A blog post at React blog: https://reactjs.org/docs/hooks-intro.html
Would pee my pants with happiness!
It looks like we're going to be releasing hooks support as an opt-in import, so you only pay for them if you use them. It'll look like this:
import { useState } from 'preact/hooks'
export function Demo(props) {
const [count, setCount] = useState(0)
return <button onClick={() => setCount(c => c+1)}>{count}</button>
}
There's been some discussion of this on Twitter - currently we have a working prototype.
@developit is there a current developing branch for hooks feature now?
What if all components stuff can also be moved into opt-in import?
Like import { Component } from 'preact/component'
So if you want to use only functional components and hooks you don't pay for component(Will|Did)...
Sure it's a breaking change but maybe someday...
Webpack should already (don't quote me on this) just remove the Component class and all other functions you don't use in your code.
Only with the proper tree shaking plugins? Or is it part of Webpack now and I've just lost touch (last option most likely)?
Webpack 4 does tree shaking in production mode (Source: https://webpack.js.org/guides/tree-shaking/) ๐
While treeshaking will remove some, It won't be able to remove this code for example:
https://github.com/developit/preact/blob/master/src/vdom/component.js#L27
or this one
https://github.com/developit/preact/blob/master/src/vdom/component.js#L86
or this
https://github.com/developit/preact/blob/master/src/vdom/component.js#L200
Moving components into their own sub-package sounds great, especially since they become useless if one go with hooks exclusively. So most projects could decide whether they want the OO style (/components) or the more FP style (/hooks)
@AlexGalays it's unlikely that they'll become "useless" anytime soon. There are a lot of third-party components on npm and it will take a long time for them to change. And that assumes that all the authors do want to change to hooks in the first place.
@AlexGalays it's unlikely that they'll become "useless" anytime soon. There are a lot of third-party components on npm and it will take a long time for them to change. And that assumes that all the authors do want to change to hooks in the first place.
Yes, I never wrote that though.
@AlexGalays Oh sorry, my bad. I misread your comment.
In order to move Component into a subpackage we'd need to disentangle it from the renderer. Right now it's plumbed directly into the renderer since setState and forceUpdate enqueue rendering. It seems like the only way to remove that direct dependence would be to export a secret member from Preact that can be used to call enqueueRender(). This could potentially be done the same way we do hooks (import {options} from 'preact'; options.enqueueRender()). I'm not sure what the savings would be though.
Is there a repo/branch for the hooks work in progress?
No pressure btw, just wondering. Perhaps I could even help :)
Any update on hooks status?
Wrote a poc, more like a code to play with until it is available from preact devs
is this currently happening guys? When could we likely we see the new react hooks api available for use in preact?
And what about Suspense, concurrent mode et al? Can Preact really keep up with all these features?
thats a good question... alot of changes happening quite quickly on the react side of things..
Hooks is happening, yes. A few folks including @AlexGalays are working on it.
Regarding the other changes, Suspense is on the table and is enabled by the fundamental changes being released in Preact X. Concurrent mode seems much less likely to be useful in a 3kB library, but who knows.
@a1pack your implementation is interesting! If you're able to join the Preact slack to chat with some folks on the core team, I think we might be interested in using pieces of it.
@developit ever thought of adding for unistore instead preact? would be more simply, right?
@thadeu I'd love to see a hooks version of unistore's connect() function:
import { useStore, useActions } from 'unistore/preact/hooks';
const ACTIONS = store => ({
setTitle() {},
navigate(state, url) { return { url } }
});
function Foo() {
const { url, title } = useStore('url,title');
const { navigate, setTitle } = useActions(ACTIONS);
return <button onclick={() => navigate('/foo')}>{title}</button>;
}
I'm glad to see this issue. I'm also working on react hooks, and I'm having difficulties.
I'm willing to contribute.
At present, I have achieved the minimum implementation of hooks.
https://github.com/132yse/fre/blob/master/packages/hooks
But the question now is triggering rerender, useState is different form setState, which do not know from which functional component call .
I guess that's related to the React Fiber
Took the experimental @a1pack implementation and added very generic typescript types, encapsulated the implementation in a module, and confirmed that this implementation works with rollup scope hoisting and tree shaking. https://gist.github.com/baetheus/d279ec135c2c54ee2c2b0209f1c8f29a
@baetheus @a1pack Your realization is not perfect. setState() will re-render render() that from current component.
If parent component rerender, child component will rerender and state will go back to the initial value
for example๏ผ
function App() {
const [sex, setSex] = useState("boy")
return (
<div>
<h2>{sex}</h2>
<button onClick={() => setSex(sex === "boy" ? "girl" : "boy")}>x</button>
<Counter />
</div>
)
}
function Counter() {
const [count, setCount] = useState(0)
return (
<div>
<h1>{count}</h1>
<button onClick={() => setCount(count + 1)}>+</button>
</div>
)
}
when I setSex ,the count will back to 0
That's why we need implementation from preact devs :) Actually I found the same issue by myself but did not had small example to reproduce it. Debugging this behavior I found that Preact unmounts an inner component (Counter in this case) and mounts back again a new instance. Actually it is not the only case where it does not work and how it does not work.
For some cases I did a fix replacing bind with anonymous class (updated POC to reflect this + added licence), but this case and one more very similar (still want to find a time to do small example) still fails.
Not sure if it is caused by POC implementation or it is a Preact bug. But if it is a bug in POC than most probably in the options.vnode even if it looks simplistic already.
Unfortunately did not had time to improve POC a lot. Also I feel like it can be optimized in many places.
In the end I spend just about 40 minutes implementing it but about a day testing and can only confirm that it is not production ready at all.
Updated POc one more time. Now it works, also I don't see problem in my more complex tests. Still left 2 points:
FYI: The hooks api will be part as an experimental feature of our next major release (titled: Preact X). The PR for it and a second one which optimizes bundle size was merged just before the weekend ๐
FYI: The hooks api will be part as an experimental feature of our next major release (titled: Preact X). The PR for it and a second one which optimizes bundle size was merged just before the weekend ๐
Great news! Dare I ask if there is an ETA on the release of X? ๐It sounds like it's going to be amazing ๐
@Anwardo We're currently aiming for a beta/rc release around mid February. We'll post an announcement at that time with more info ๐
Quick update: We're currently working on adding the last missing piece to hooks wich is the new context api via useContext. We originally didn't plan to include it in the initial release of Preact X but due to popular demand and widespread usage of createContext we decided to include it :+1: The PR's for it are already there and are awaiting review and some size reductions.
The downside is that this will slightly affect the release date. March seems like a more realistic estimate right now :+1:
@marvinhagemeister umm is it possible to peek at the code somewhere? grepping for useState doesn't return anything in developit/preact, developit/* or marvinhagemeister/* :)
@wizzard0 Preact X currently lives in a private repo but will be merged soon into this one here. The switchover date is March 4th. See: https://mobile.twitter.com/marvinhagemeist/status/1097973028426788864 ๐
We just merged the PR for Preact X #1302 which includes the hooks addon. An alpha release should be available in a few hours :tada:
Any idea of when the hooks documentation / API reference will be live?
@Xeoncross Updating our docs (and our site in general) is on our roadmap, but it's hard to tell when that will be finished. In Preact hooks work exactly the same as in React so their docs for hooks match perfectly. The only difference is the import: preact/hooks vs react :+1: :100:
I think I'm running into a compatibility problem with react-wordcloud. Running the example from the readme in a new Preact 8.4.2 app fails with
useRef is not a function
After installing preact@next and adding import { useRef } from 'preact/hooks', the error becomes
preact.js?10a9:1 Uncaught TypeError: Cannot read property 'default' of undefined
at rankChild (preact-router.es.js?bff2:82)
at prepareVNodeForRanking (preact-router.es.js?bff2:65)
at Array.filter ()
at Router.getMatchingChildren (preact-router.es.js?bff2:303)
at Router.render (preact-router.es.js?bff2:326)
Installing preact-compat didn't help.
you want preact/compat, not the old preact-compat
@ForsakenHarmony: after removing preact-compat and installing preact/compat, I get
TypeError: Cannot read property 'replace' of undefined

do you have the latest preact-router?
Most helpful comment
It looks like we're going to be releasing hooks support as an opt-in import, so you only pay for them if you use them. It'll look like this:
There's been some discussion of this on Twitter - currently we have a working prototype.