-
Notifications
You must be signed in to change notification settings - Fork 48.5k
Feature Request: Provide an optimization option for simple stateless components #20564
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
Hey @bglgwyng, thanks for taking time to write out this proposal. Isn't this what |
const HeavyComponent = React.memo(() => {
useEffect(() => { console.log("mount!") }, []);
return <span>hi</span>
}); If |
Why not to simply expose functions like Or you can expose default props for each variant: function Cmp() {
const defaultProps = state ? defaultPropsA : defaultPropsB
const props = {
...defaultProps,
customProp: "foo"
}
return <HeavyComponent {...props}>
} Or pass a prop that denotes specific variant function HeavyComponentOfType({ type, ...props }) {
switch (type) {
case "A": return (<HeavyComponent someProp="true" {...props}>);
case "B": return (<HeavyComponent someProp="false" {...props}>);
default: (() => throw new Error('Unknown type'))()
}
} |
@rickhanlonii This issue is a variation of a request for reparenting support (#3965). Some components (subtrees) are expensive to create/destroy but there's no way to move them around other than destroying and recreating (and also lifting up/restoring any state that goes along with them). I'm not sure the proposed mechanism makes sense to me though. In the very simplified example given, the proposal would be overkill obviously– and I'm not sure if it would make sense in a larger, more "real world app" context. Definitely seems like something that would need to go through our RFC process regardless: https://github.com/reactjs/rfcs#react-rfcs That being said, the RFC process moves very slowly due to our small team size. |
I'm going to tag this as "discussion" but I don't think it's a complete enough proposal for much of a detailed discussion to take place. I still think it should be an RFC instead. That process kind of requires thinking through pros and cons a little more. That being said, for a discussion to be fruitful here, I think we need at least one more realistic example. The original example shared doesn't really make much sense and so the proposal would not be needed. I'm not convinced that the proposal would make sense in a larger, more real-world application either, but maybe we could start off by looking at something more representative of one. |
It's been a couple of months and the discussion seems to have dead ended without any additional examples or use cases, so I'm going to close this issue. |
Please look at the following code first.
HeavyComponent
is literally a heavy component that requires large computation for rendering. Assume that nobody wants the scenario thatHeavyComponent
mounts and unmounts frequently.And as you can see,
A
andB
do very simple jobs. They are just tiny components that just wrapHeavyComponent
in each different way.A
andB
can be switched to each other in bothC
andD
. The rendering result will be the same inC
andD
. But the internal behaviors differ from each other.C
causesHeavyComponent
to mount whenever it rerenders, whileD
doesn't. If there areuseEffect
calls with emptydeps
insideHeavyComponent
's body, then they will be called each timestate
in C changes, while they won't withD
. So,D
is better in performance thanC
.However, the problem is that
A()
andB()
are not the recommended style in React code. IfA
andB
are used only inside the module not being exported to others than the author, thenA()
is an acceptable hack. But sometimes, at least in my case, components likeA
andB
should be exported outside the module. And it's hard to expect users of my library to useA
andB
in an efficient way like insideD
. I hope there is a way to let users use<A />
instead ofA()
not worrying about the performance.I think you can point out that I don't need to define
A
andB
and I can useHeavyComponent
directly instead. But it's just a simplified example. In real practice, I have more than one props and also more components. Each component represents the semantic of the combination of props passing toHeavyComponent
by name of itself.I'll also export
HeavyComponent
directly, but users will get confused about its props at the first glance. So it would be better to export handy componentsA
andB
also.I suppose the implementation would not be complicated. The following is my psuedo code.
I said stateless in the title, but hookless would be the correct condition.
useEffect
,useRef
and other hooks are not permitted inside the body of simple components. Of course, I don't think simple is a good name. I'll be happy to see suggestions.Does this seem a reasonable option to consider?
The text was updated successfully, but these errors were encountered: