-
Notifications
You must be signed in to change notification settings - Fork 1.2k
tie together setDisplayName
+wrapDisplayName
+getDisplayName
#299
Comments
Do you mind to describe what are |
Thanks for the response. Can you take a look at this webpackbin? It's a contrived example where I have a presentational component that I want to wrap with a container component that will make it so that it will log to console when the base component is added to the DOM. In this example I'm using So you see how in LMK if I'm still being unclear. Thanks. |
Thanks for sharing your code! In your case, is there any concern to use a string directly instead of calling I mean changing your code from let newDisplayName = wrapDisplayName(WrappedComponent, getDisplayName(LogComponentDidMount)); to let newDisplayName = wrapDisplayName(WrappedComponent, 'LogComponentDidMount'); |
Thanks. Well, maybe I'm nit picking, but there's a difference. Because in the 2nd case I would violate the DRY ("don't repeat yourself") principle. If I change the name of the class Obviously, this is not a big deal for a single use-case in your code. But assume that you have many different custom HOCs. Calling all three of these functions together can be cumbersome. Makes sense? Thanks. |
@cowchimp It makes sense to me. Moreover, I think we can use |
cool, I'll work on it. Can you please explain why you avoid requiring
? you also do something similar here
thanks. |
It's used to increase performance and reduce the bundle size. |
I would love to see the api for manipulating component names simplified in this way. Ever since I started using recompose (changed my React life, btw), I've wondered about what an api that handled the most common use-case would look like. The ideas discussed here seem right on target. Can't wait to see it. |
@jcheroske glad to hear that Recompose can help you rethink React. I'm going to close this issue for now and a PR to refactor the code is still welcome. |
I think we should leave this one open with a PR Welcome tag. It shouldn't
be too hard.
On Tue, Feb 28, 2017 at 4:24 AM CT Wu ***@***.***> wrote:
@jcheroske <https://github.com/jcheroske> glad to hear that Recompose can
help you rethink React. I'm going to close this issue for now and a PR to
refactor the code is still welcome.
—
You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub
<#299 (comment)>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/AAKQblRpUM3arUibAkve_ymH6emBTaplks5rg-fZgaJpZM4LZ64W>
.
--
- Tim
|
Can we have more of a discussion about what the community would like to see on this front? Specifically, heavy use of
Just thinking out loud here... |
The nested HOCs will be flattened after #182. And it would be better to open a new issue to discuss customized HOCs' names. |
I just read #182. You guys are way ahead of me. I say close this and we can pick this up on the other side. |
No I think we leave this still open. |
I'm agree with @timkindberg. These are different requests. |
I think if import { connect } from 'react-redux';
import { compose, setDisplayName, wrapDisplayName } from 'recompose';
import * as actions from '../../actions/account';
export default compose(
connect(state => ({
account: state.account,
}), actions),
chain( // helper from an fp library like ramda
setDisplayName,
wrapDisplayName('withAccount'), // could be curried, but currently doesn't work like this
),
); |
This is a very simple thing to add.
|
@timkindberg I think more than half of recompose's hocs and helpers are easy to implement, but that's what this project is for — to be a toolbelt of helpful stuff that you might often wish to use. So my comment was not a question of "how" but rather wondering whether this is not something that many people find themselves needing to have. |
@everdimension true. Our team certainly needs it. I think it's very common and should be in the library. |
Having that it mostly debug enhancers why their are common? |
Well think about it. Recompose is a toolbelt for writing our own Higher Order Components. HoCs need nice display names. Since HoCs wrap other components it is common that we need to set the wrapped display name for our custom HoCs. It is a trivial but important util to have in the library. |
So what const enhance = compose(
mapProps(/* do something */),
setWrappedDisplayName('customizedName'),
mapProps(/* do something */),
)(Foo) Will show this in devtool: But I think what you want is |
That's a good question. I typically use it to "Name" my HOC once I'm done coding it. So I'd typically use it at the top of a composed set of HOCs. const withCoolFeatures = compose(
setWrappedDisplayName('withCoolFeatures'),
mapProps(),
lifecycle(),
connect(),
whatever,
)(Foo); I'd want to see a displayName of |
I just wanted to chime in and say that I, for one, like the idea of adding more helpers to recompose. I'm currently learning rxjs, and it has over a hundred operators I think. Many are simple derivations of others, analogous to the mapProps -> omitProps situation in this lib. I love that rxjs just gives you all the helpers. Just imagine how many omitProps implementations are floating around out there. Yikes! |
@timkindberg I like the idea, but I don't think there is a way to achieve it without modifying other HOCs in recompose. |
From what I can tell, the issue is that HOCs like https://github.com/acdlite/recompose/blob/master/src/packages/recompose/withProps.js don't pass through the Another use case (i.e. mine 😉) where having access to the |
Bit awkward right now, but this is the solution (based on @timkindberg 's HOC) I came up with: const setWrappedComponent = BaseComponent => setStatic('WrappedComponent', BaseComponent)(BaseComponent);
const setWrappedDisplayName = name => BaseComponent =>
setDisplayName(wrapDisplayName(BaseComponent.WrappedComponent || BaseComponent, name))(
BaseComponent,
);
export default () =>
compose(
setWrappedDisplayName('toggleable'),
// other HOCs
hoistStatics(withState('toggled', 'setToggled', false)),
hoistStatics(
withHandlers({
toggle: ({ setToggled }) => () => setToggled(n => !n),
}),
),
// ... and finally
setWrappedComponent,
); |
@hardchor cool! You could totally make that into a reusable function. Call it |
@timkindberg @hardchor I think const namedCompose = wrapperName => (...hocs) => BaseComponent =>
setDisplayName(
wrapDisplayName(BaseComponent, wrapperName) // build wrapped name
)(
compose(...hocs)(BaseComponent) // build enhaced component
) and use like this export default namedCompose('toggleable')(
withState('toggled', 'setToggled', false),
withHandlers({
toggle: ({ setToggled }) => () => setToggled(n => !n),
}),
// ...
) @wuct for naming intermediate, I tried this const wrapName = wrapperName => ({
$$composeWithIntermediateNaming: true,
name: 'wrapperName',
})
const composeWithIntermediateNaming = (...hocs) => BaseComponent => compose(
...hocs.map(
hoc => hoc.$$composeWithIntermediateNaming ?
setDisplayName(wrapDisplayName(BaseComponent, hoc.name)) :
hoc
)
)(BaseComponent) and the usage would like below const enhance = composeWithIntermediateNaming(
mapProps(/* do something */),
wrapName('customizedName'),
mapProps(/* do something */),
)(Foo) but I would like use const enhance = compose(
mapProps(/* do something */),
namedCompose('customizedName')(
mapProps(/* do something */),
),
)(Foo) |
Or If a string is passed in as the only arg, then it returns a 'named' compose function. compose('MyName')(...hocs)(BaseComponent); Otherwise it works as previous: compose(...hocs)(BaseComponent); |
@timkindberg Not a big fan - that'd completely change the function signature. |
@burkhardr it would be backwards compatible. So the signature would break and we'd avoid YAHOC (Yet another higher order component). |
Ill close this. Feel free to reopen if you think that this discussion is not the road to nowhere |
Hi.
setDisplayName
,wrapDisplayName
, andgetDisplayName
are powerful utilities.But IMHO there should be a utility function that ties them all together for a very common scenario.
The most common pattern I see around naming HOCs is
WrappingComponent(WrappedComponent)
so now, in order to give that name to
WrappingComponent
I need to use all three utility functions and to do:So, two there are two things that are left to be desired here IMHO
wrapDisplayName
callsgetDisplayName
internally forWrappedComponent
but not forWrappingComponent
(which is why I have to usegetDisplayName
in the user code for that).This could be modified so that
wrapDisplayName
will be able to accept a component as the 2nd parameter as well (an overload of sorts), and internally callgetDisplayName
on it. This is a pretty low-risk breaking change because right nowwrapDisplayName
expects only a string, so modifying this should extendwrapDisplayName
, not break it (andgetDisplayName
already returns a string if it gets a string).WrappingComponent
reference and theWrappedComponent
reference, will calculate theWrappingComponent(WrappedComponent)
name and set it as the new name forWrappingComponent
.This could be a new utility called setWrappedDisplayName`.
For example:
Would be happy to try to send in a PR if we can decide on the necessary changes.
Thanks!
The text was updated successfully, but these errors were encountered: