Disclaimer: I'm super jet-lagged and my brain is only half working at the moment, but since Dom asked me to take a look- I think I like option-e the best. 😄
I do have a thought or two:
example-a: I'm curious why React.createState returns a function instead of a state? Doesn't seem obvious why that's necessary since it doesn't accept any arguments. Is it just to make it more comparable to the others?
example-e: Does the CounterComponent function even need to exist? All it does is relay props. Could reduce boilerplate a little with just:
I'd also like to learn a little more about the constraints of didUpdate. What types of things- other than tweaking refs- is it okay to do in this lifecycle? (Is there anything that's safe to do in eg componentDidMount that it won't be safe to do in didUpdate without causing deopts?)
@bvaughn I've updated example E after speaking with Dan. I think example A and B are probably going to be no goes because of the overhead they add in the render phase. The naming of createState() was also probably not the right name for this method.
The reason I went with different lifecycle names was purely to avoid confusion with existing ones – as the arguments passed wouldn't match up. I'm not fussed on name, I just didn't want to create more confusion. We could also infer async by default with some of them, to help the async story more (rather than sync like they are now).