React just published a blog post about upcoming api changes due to the planned suspense api. The current lifecycle methods will be deprecated with react v17.
We should decide if we want to follow them or leave the lifecycle methods as is. Note that our rendering process is currently not asynchronous but synchronous so we don't have the same problems as them.
List of API changes recently introduced by react:
getDerivedStateFromProps (#1094)getSnapshotBeforeUpdate (#1112)componentDidCatch (#819)Fragments (#1080)new Context API: currently no interest in bringing this into core (may change). preact-context is sort of a polyfill that can be used todayUNSAFE_componentWill* won't be added to preact, simply continue using componentWill* hookscreateRef (#1138)createPortalIf I may just add my 2 cents: the getDerivedStateFromProps function in particular sounds like a very worthwhile addition.
I ended up creating my own personal version of it using componentWillReceiveProps and the constructor for every project where I've used preact so far (which, to be fair, has only been a couple of them during the last year).
Maybe I'm working with an anti-pattern and still haven't realized it but plenty of times I want to setup some sort of state that needs to be updated whenever props change.
Thanks @marvinhagemeister for sharing that
IMO for now, before to decide anything, we should take a look how v17 looks like while development, and thats not tomorrow. Probably this discussion should be delayed till that time (when that version is released and anyone can bring their opinion). Since React and Preact have a very similar API but way different implementations and current React API its more like an standart so for the moment users and new comers will be very confortable as it is right now and so on. Im very skeptic about changes that doesn't give us anything better..
Agreed regarding getDerivedStateFromProps - it's just a convenience wrapper around a common pattern. We can try it out, and if the implementation is tiny enough then it's nice to have compatibility.
It might also be useful to see if there are any shining examples of where getDerivedStateFromProps is useful, if anyone has them.
React still intends to leave the existing methods even after v17, just with the UNSAFE_ prefix.
getDerivedStateFromProps though sounds like a really good thing to have. The issue is that it's exclusively setting state, while some people (like me) do other things in componentWillReceiveProps
My use case for getDerivedStateFromProps:
I have a component that includes a little calculator. The calculator is a pure function which requires a price field and a currency field, the values for which are handled by a higher-up container and passed down via props.
In the calculator, if the currency is updated, I call a method on the higher up container (also passed down via props) to update the currency higher up. This passes the props change back down to the calculator component where getDerivedStateFromProps would intercept it and update the calculations.
I actually wrote all the code for it before realizing that getDerivedStateFromProps is not yet implemented in preact, so for now I will update it to use componentWillReceiveProps.
An annoyance with having to do it this way is that I'll need to call the function on both componentDidMount and componentWillReceiveProps (in different ways because they pass different parameters).
My 2c.
since componentWillUpdate is going to be deprecated, it's not good to rely on it for new code as we'd have to replace it at some point. That's why I'd like to be able to use getSnapshotBeforeUpdate.
getSnapshotBeforeUpdate might be tricky with a one phase reconciler as it inherently assumes a two phase reconciler, since it is called after render but before the update is committed to the DOM and before componentDidUpdate.
Oh, I haven't realized before that it was called after render. It seems it will no longer be possible to compare against the previous state during render through the hooks, which was my use case, since I wanted to detect whether an specific state had changed. Anyway, I've implemented this check without using any life-cycle hooks, so I no longer have a real need for getSnashotBeforeUpdate.
FYI, I'm working on a WIP getDerivedStateFromProps implementation in my preact fork (the implementation). Still validating the implementation in unit tests.
Currently coming in at +34 bytes over master (master: 3443 bytes -> getDerivedStateFromProps: 3477 bytes).
EDIT: updated links to branch from PR
@andrewiggins That's awesome 馃帀 Happy to help if any questions come up 馃憤
Opened PR #1094 for getDerivedStateFromProps
componentWillReceiveProps is the only way I know of to get around the issue with component recycling. I don't think there should be any movement on an API change until there's a decision made on the removal of component recycling.
Here's an example of how I'm using componentWillReceiveProps to force a complete rerender of a component in case anyone has a better way to get around the component recycling.
class Image extends Component {
constructor(props) {
super(props);
this.state = {
doRender: true
};
}
componentWillReceiveProps() {
this.setState({
doRender: false
}, () => {
this.setState({
doRender: true
});
});
}
render (props) {
if (this.state.doRender) {
return <img src={props.src} />;
} else {
return <div></div>;
}
}
}
PS: Thanks @developit and everyone else who contributes to this awesome project.
FWIW I don't see a reason why getSnapshotBeforeUpdate can't be implemented in Preact. That said, I also don't understand why that method even needs to exist.
We talked a bit on how we want to deal with the upcoming changes in yesterdays meeting. The general conclusion was to keep componentWill* hooks for now and add the new API getDerivedStateFromProps and getSnapshotBeforeUpdate. We won't add the UNSAFE_componentWill* hooks like react did.
The reasons for changing the api are outlined in the react announcement post or in the original getDerivedStateFromProps and getSnapshotBeforeUpdate rfcs. Note that some arguments made there don't apply to preact because our rendering is synchronous. To summarise:
getDerivedStateFromProps:
props or statePersonally, I never thought that'd be an issue until I stumbled upon a component at work that mutated both state and props in componentWillReceiveProps. Moreover the author of that code was confused why componentWillReceiveProps is not called when the component is constructed.
getSnapshotBeforeUpdate:
static in the initial RFC but later changed back to a normal methodcontext argument like componentWillUpdate.At this point I'm not sure if we need this for preact. Perhaps an alias is enough?
My 2 cents:
deprecate componentWillMount. Never came across a situation could not be solved with componentDidMount instead.
deprecate componentWillUpdate. Again never came across a case that can not be solved with either componentWillReceiveProps and/or componentDidUpdate
The removal of the ifs alone in the code for above lifecycle hooks will reduce the file size.
Regarding componeWillReceiveProps. The official react documentation at the moment provides an example of react integration with other libraries (extracting data from model) making use of it and I can not think of a simple way of achieving that only with the non deprecated lifecycle methods. I would just wait to see what the community will come up with before just deprecating it.
@marvinhagemeister I would say that https://github.com/developit/preact/pull/879 is an actual requirement for Fragments, what do you think?
@k1r0s No, it is not a hard requirement.
// babel 6
import { Fragment聽}聽from "preact";
const foo = <Fragment>hello world</Fragment>
// babel 7
const foo = <>hello world</>
I already knew that wut.. ig is too risky to release preact fragments without using babel 7 :\
Closing because all of the listed features will be available in Preact X. An alpha release is scheduled to drop on March 4th :tada:
It seems ref forwarding isn't planned. Do you guys wish to implement it in the future ?
@rewieer I have some good news: forwardRef is already available in Preact X. It lives in preact/compat and an alpha release is already out on npm to enjoy馃帀馃挴
Wow nice ! Thanks for the feedback and the quick reply, you guys are awesome 馃挴
Most helpful comment
We talked a bit on how we want to deal with the upcoming changes in yesterdays meeting. The general conclusion was to keep
componentWill*hooks for now and add the new APIgetDerivedStateFromPropsandgetSnapshotBeforeUpdate. We won't add theUNSAFE_componentWill*hooks like react did.The reasons for changing the api are outlined in the react announcement post or in the original getDerivedStateFromProps and getSnapshotBeforeUpdate rfcs. Note that some arguments made there don't apply to preact because our rendering is synchronous. To summarise:
getDerivedStateFromProps:propsorstatePersonally, I never thought that'd be an issue until I stumbled upon a component at work that mutated both state and props in
componentWillReceiveProps. Moreover the author of that code was confused whycomponentWillReceivePropsis not called when the component is constructed.getSnapshotBeforeUpdate:staticin the initial RFC but later changed back to a normal methodcontextargument likecomponentWillUpdate.At this point I'm not sure if we need this for preact. Perhaps an alias is enough?