-
Notifications
You must be signed in to change notification settings - Fork 1.3k
Remove createEagerFactory and createEagerElement #538
Conversation
Codecov Report
@@ Coverage Diff @@
## master #538 +/- ##
==========================================
- Coverage 88.94% 88.37% -0.57%
==========================================
Files 53 49 -4
Lines 389 370 -19
==========================================
- Hits 346 327 -19
Misses 43 43
Continue to review full report at Codecov.
|
Super, wiil publish today-tomorrow! |
First time in my life I see usage of react createFactory in a wild |
well I just tried to have the minimal diff :) we can go with JSX instead. |
The minimal diff is fine for me, with JSX I think it will be a problems with preact etc |
But there is no |
@istarkov Thanks! This PR looks good to me now :) |
Thank you!!!!! |
I'm curious about the motivation behind this change. Are you saying it's playing with fire forcing this performance optimisation, when instead, it could be something done by React internally?
Also, I never understood why this performance optimisation has been enable for production only at some point. Why not keeping it for all the env? Thanks for your 💡. |
Initially all began here #442 (PR #473), at that time optimisation already worked differently at production and development (but for PropTypes case) and also was a point of problems with enzyme tests. But just that change wasn't the point of following problems ;-)
Having that react vdom is very fast - and having that at dev I see no performance problems last month+ (I know that it is very bad test - "I see no perf problem") we decided to remove it. |
I've asked @acdlite here https://twitter.com/icelabaratory/status/916360249635999744 |
@istarkov Thanks a lot for taking the time to answer the question in detail! Keep the good work. |
Shouldn’t this public API removal be considered a breaking change? Someone could be relying on these factories in their own HOC implementations. |
minor version bump while major is zero is already a breaking change according to semver. |
My bad, should’ve been clearer - perhaps having the word BREAKING in the release notes would’ve been clearer, but maybe it’s implicit from the minor version increase 😅 |
* export `createEventHandlerWithConfig()` and add documentation. * Fix Prettier issues * Docs: Fix missing comma in type description for `createEventHandlerWithConfig()` * Docs: Add *WithConfig functions to TOC. * Use $Compose instead Compose (acdlite#523) * Use $Compose instead Compose * Update flow-bin dependencies * Allow React 16 (acdlite#530) Resolves acdlite#506. * recompose v0.25.1 * Updated base fiddle link (acdlite#534) Base fiddle was using a unpkg link pointed at the old (React 15) dist url but without a React version, so broke with the release of React 16. Now points to the correct location for React 16, with 16 specified (shouldn't break this way again). * Remove createEagerFactory and createEagerElement (acdlite#538) * recompose v0.26.0 * Fix grammar in API.md (acdlite#542) * Translate `createEventHandlerWithConfig()`
* export `createEventHandlerWithConfig()` and add documentation. * Fix Prettier issues * Docs: Fix missing comma in type description for `createEventHandlerWithConfig()` * Docs: Add *WithConfig functions to TOC. * Use $Compose instead Compose (acdlite#523) * Use $Compose instead Compose * Update flow-bin dependencies * Allow React 16 (acdlite#530) Resolves acdlite#506. * recompose v0.25.1 * Updated base fiddle link (acdlite#534) Base fiddle was using a unpkg link pointed at the old (React 15) dist url but without a React version, so broke with the release of React 16. Now points to the correct location for React 16, with 16 specified (shouldn't break this way again). * Remove createEagerFactory and createEagerElement (acdlite#538) * recompose v0.26.0 * Fix grammar in API.md (acdlite#542) * Translate `createEventHandlerWithConfig()`
@istarkov Was a different option for eager optimizations discussed? For e.g. only supporting functional components? |
Looking for Checking for @developit @istarkov Please feel free to reach out to us next time you need to check something like this. We’re happy to explain motivations for why went for a particular check. |
@kof the main issue was our inability to distinguish functional component from class component, both are functions (class is still a constructor function), both can have no render function in prototype, there were non documented method for React (now documented |
I haven't looked yet into each issue, but
yeah should not happen, this optimization should be always in place if at all
If it is about adding isReactComponent I am sure @developit will accept a pr for this. |
what would be (and it actually was) really misleading to many people is that you can't find something in React elements tree using Enzyme or similar tools because it was automagically "squashed" by quite internal and advanced condition check. dev tools prettiness is doomed in any way because we still have stateful HOCs even if we can just call the rest as functions. |
What about a separate function which does the optimizations? |
it may play well at least for me if it's easy to alias it using some Babel plugin or Webpack only in production mode, just like react → preact seamless transition. |
Here's something I don't understand. I agree that in general the edge cases of "executing" arbitrary user-provided components can be too confusing, and Recompose probably shouldn't attempt to do that by default. But can't Recompose safely collapse its own components? E.g. |
yeah, its dangerous to have different behavior in production, much better to stick with it everywhere. |
I think it should be safe to bring back if you do this only for Recompose components. Then you don't need flaky checks about whether something is a class or not—because you have full control over the components. |
then as you already proposed it should be an explicit opt-in – this way user is more or less aware of what's going on.
I'm all for it if we have a proper way to do this – does Andrew's tweet mentioned above still make sense? |
I can't say if a tweet "makes sense". I'm not sure what you're asking. React won't do this optimization for now because it's not very useful to apply it everywhere. And it's something a compiler is better positioned to do. But I'm not sure I'm seeing a problem with Recompose being a bit smarter around its own components. Maybe I'm missing something. |
From my side I see nothing bad to accept PR which will not cause any issues we had before. I wanna ask people how looks like your longest streak of composed recompose HOCs in current project. As having modern tools like As an example my current longest recompose streak looks like below (just parsed my code base)
What the performance benefit will be achieved on some kind of real example? |
I've seen some wild |
I landed in this discussion because I joined a project where I see an input field with 16 HOCs. I decided to dig into it because it didn't seem right. Now I am wrapping my had around why that happens and where it needs to be fixed. Right now it seems it is both - recompose and our code. In general as an architect I am looking for a way to guide other developers on how to write code without landing in this mess of 16 HOCs input. |
from what I got from that tweet is that |
We chatted with @acdlite today and agreed this might be a reasonable path:
|
So we have a way to identify a react class based component, but we have no way to identify a functional one. What if we could use for e.g. Component constructor as a factory to create a component from a function? import {Component} from 'react'
const Button = Component((props) => <button></button>)
Button.isFunctionalComponent // true Now we could do optimizations with user components as well, right |
Why do you need to identify them? Recompose components could be tagged with its own flag which Recompose components would check. |
Oh I missed the last sentence. I don’t think this makes a lot of sense for a few reasons. Feel free to raise a suggestion on React RFC repo but I don’t see people rewriting all components like this. In any case this seems unrelated to the discussion. |
Me neither unless there are more reasons to be able to detect a functional component. For now it could be just recompose. Recompose could do heavy lifting for user components if it knows they are functional components. |
I'd vote for special static property to be able to mark any other "3rd party" HOC with it. at the same time it feels like it should be kinda internal Recompose thing exposed only for HOCs authors, at least at this point and mostly to not create unnecessary confusion. |
I suggest not trying to over-abstract and focusing on this specific problem which should be soluble. |
So are we talking about a special static property? I'd really like to allow 3rd party HOCs passed to
|
So far my idea is something like this: import { createElement } from 'react'
export const isFunctionalHocSymbol = 'IS_FUNCTIONAL_HOC_OR_BETTER_NAME'
export const createEagierElement = (type, props, ...children) => {
if (typeof type === 'function' && type[isFunctionalHocSymbol] === true) {
if (children.length === 0) {
return type(props)
}
if (children.length === 1) {
return type({ ...props, children: children[0] })
}
return type({ ...props, children })
}
return createElement(type, props, ...children)
} Probably we can even omit |
closes #489, as discussed.