Emotion: useCss hook

Created on 18 Apr 2019  Â·  6Comments  Â·  Source: emotion-js/emotion

@mitchellhamilton hey, I'm not sure if this is possible because I don't know the exact internals of emotion, but from a conceptual level this might make sense.

I'm wondering if we could do something like

const MyComponent = props => {
   const theme = useContext(ThemeContext);
   const className = useCss({color: theme.red});
   return (
     <div className={className}>
       MyComponent
     </div>
    );
}

any thoughts?

from a birds eye view, some thoughts here are, you now don't need to worry about shouldForwardProp
you don't need to interpolate with color: ${props => props.theme.red} and the entire component doesn't need to be wrapped, if the ref needs to be forwarded, then you just use forwardRef, etc.

Most helpful comment

We'll rethink how this problem can be handled right now. We are working on a v11, so we'd like to address problems like this. The solution is not obvious - so no promises yet, but please know that we are going to think about this.

All 6 comments

The main issue with the React Hooks version of ClassNames (basically, what you are suggesting here), is that the css call needs to render the style tag in the same context where it's used (this is needed for server side rendering compatibility).

React Hooks don't render anything.

A possible solution would be to have the hook find its closest "Emotion" parent (either a styled component, a ClassName component, a ThemeProvider or anything else that has the ability to render in the DOM.

But this may introduce some unexpected behaviors.

Also useStyle would probably be a better name for the hook :smile:

Would an API like this be possible:

const MyComponent = props => {
  const theme = useContext(ThemeContext);
  const [Stylesheet, classNames] = useStyles({
    foo: { color: theme.red }
  });
  return (
    <>
       <Stylesheet />
       <div className={classNames.foo} />;
    </>
  );
};

Following the migration from emotion@9 to emotion@10 with react-toastify, I am also facing an issue here.
I have the following hook:

function useSuccessNotification(valid, message) {
    useEffect(() => {
        if (valid) {
            toast.success(message, {
                className: css({
                    ...
                })
            });
        }
    }, [message, valid]);
}

Far away from any render, So I cannot use the ClassNames render prop tip. A hook would be really nice.

Do you see how I could make it work without using deprecated library?

We'll rethink how this problem can be handled right now. We are working on a v11, so we'd like to address problems like this. The solution is not obvious - so no promises yet, but please know that we are going to think about this.

@Andarist Are there any news about this? Did you discuss if you'd like to implement something like that, or didn't yet get a chance?

I'd really like this kind of an API. Even if with limitations — there are runtime-only environments where this could be really nice, and in others I like the proposal with a StyleSheet returned from the hook (though, I would reverse the order: [className, StyleSheet]), or a shared Context could be used as well.

The extra bit of setup would be needed to do only once, while the profit from the DX would be much bigger.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

yonatanmn picture yonatanmn  Â·  29Comments

Enalmada picture Enalmada  Â·  27Comments

mitchellhamilton picture mitchellhamilton  Â·  82Comments

JustinTRoss picture JustinTRoss  Â·  26Comments

orpheus picture orpheus  Â·  35Comments