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
Use hooks #2342
Comments
Can you add this to the v5 rollup ticket? |
I'm 👎 on this because there are use cases where you need the theme in bound functions and that flow becomes awkward without dependency injection. |
Hooks work fine with flow. |
We could probably introduce a |
Something like: const className = useStyle`
color: ${p => p.theme.colors.red};
`; Is that possible, using a TTL as a hook? |
I thought styled components are against classes. How are you gonna implement SSR with this? |
@probablyup Exactly what I had in mind. |
Emotion introduced jsx pragma to solve SSR problem. |
What do you mean? Like React classes? Ideally we'd like to use lighter representations in the library for things, but we have no overall objection to them. |
I don't really like this, that would fit better in a separate / complementary library based on the same (new) core StyleSheet infra to share code. Maybe |
I guess so? Would be pretty easy to add and just another way to do things. |
Yeah but it does not fit well into the "never see another class again"-thing that the entire styled-components API has right now. I would much rather this (seemingly "lower-level") hook live in another package, especially once we land the monorepo refactor (#2326) and the new StyleSheet infra (which will also be a separate package) it should be easy. |
I'd kind of rather it just be a different subfolder inside styled-components rather than a separate package. I am extremely against the emotion way of doing things where you have to consume 5-7 different packages. |
I do not like that either at all, I think the new StyleSheet infra does need to be a separate package that's set as a dependency on Does that make sense? |
interface FooProps {
title: string;
description: string;
bold: boolean;
}
function Foo(props: FooProps) {
const { title, bold, description } = props;
const theme = useTheme();
const Wrapper = useStyled.div`
padding: 10px;
`;
const Title = useStyled.h1`
color: ${theme.primary};
font-weight: ${bold ? 'bolder' : 'normal'};
font-size: 18px;
`;
const Description = useStyled.div`
font-weight: ${bold ? 'bold' : 'normal'};
font-size: 12px;
`;
return (
<Wrapper>
<Title>{title}</Title>
<Description>{description}</Description>
</Wrapper>
);
} Such API would work for me. It happens very often than a component has many private components. It's overwhelming when using it with TypeScript, because you must add a type annotation to every child components. In the above example, only the parent component is annotated. |
In the meantime, here is an exemplary hooks implementation: import styled, { css } from 'styled-components';
export const useStyled = (callback: ({ styled, css }) => JSX.Element): JSX.Element => {
const Element = React.useRef(null);
if (!Element.current) {
Element.current = callback({ styled, css });
}
return Element.current;
}; import { useStyled } from './hooks';
const MyComponent = (props) => {
const Container = useStyled(({ styled, css }) => styled.div`
background: #000;
${props => props.inverse && css`
background: #fff;
`}
`);
return <Container inverse={true}>Hello world</Container>;
}; |
Here is my version from the example above. Purpose:
// OLD WAY
interface OldProps {
className?: string;
children: string;
}
const OldApproach = styled((props: OldProps) => {
// compute something here
return <div className={props.className}>{props.children}</div>;
})`
// styles here
`;
// NEW WAY
interface NewProps {
children: string;
}
const NewApproach = (props: NewProps) => {
// compute something here
const Wrapper = useStyled.div(`
// styles here
`);
return <Wrapper>{props.children}</Wrapper>;
}; Demo Syntax: interface FooProps {
title: string;
description: string;
}
export function StyledSample(props: FooProps) {
const { title, description } = props;
const [bold, setBold] = React.useState(false);
const Wrapper = useStyled.div(`
padding: 10px;
width: 200px;
text-align: center;
`);
const Title = useStyled.h1(`
font-weight: ${bold ? 'bolder' : 'normal'};
font-size: 20px;
`);
const Description = useStyled.p(`
font-weight: ${bold ? 'bold' : 'normal'};
font-size: 14px;
`);
// this should be a shared component
const Button = useStyled.button(`
color: white;
border-radius: 3px;
padding: 0.25em 1em;
margin: 0.5em 1em;
border-width: 2px;
border-style: solid;
border-color: palevioletred;
border-image: initial;
background: palevioletred;
`);
return (
<Wrapper>
<Title>{title}</Title>
<Description>{description}</Description>
<Button onClick={() => setBold(!bold)}>toggle bold</Button>
</Wrapper>
);
} CodeSandbox https://codesandbox.io/s/3yl3wm6zp |
@BetterCallSKY Hey, I like that way of using styled hooks! I tried taking your useStyled.tsx from the codesandbox, but some errors with Typescript come up. Error at line 156
Error at line 158 to 160 (
Any idea how to fix those? Using SC v4.1.3 |
Try to use a newer version of Typescript. microsoft/TypeScript#28795 |
Did you mean older? Because I already tried with the latest one (3.3.4000). I tried going to Typescript 3..1.x since the original post suggests it worked before 3.2.x, but that didn't work... Also tried the codesandbox version of Typescript (3.3.3) which also didn't work. Tried changing to
Could this be a compiler option? For now, I've added a export const useStyledCustom = (Component: React.ComponentType<any>) => {
const ret = (css: string) => {
const Inner = React.useRef(styled(Component)`
${(props: any) => props.css || ""}
`).current;
return React.useCallback(
React.forwardRef((props: any, ref: any) => (
<Inner ref={ref} {...props} css={css} />
)),
[css],
);
};
return ret;
}; EDIT 2: |
I have been using styled-components for only few months now and I find it a bit cumbersome with react hooks. Is it still necessary to have functions as template string arguments now that we have hooks in react? Wouldn't something like this match better with hooks pattern?:
or
|
It feels to me whenever a new pattern arises. "we must use this for everything!" doesn't make any sense to me. It would however make sense for just a couple of API's such as |
In this case it ends up majorly simplifying our internal structure, so we
definitely want to do it. We’re also exposing our ThemeContext so you can
just do useContext(ThemeContext).
|
Would it make easier to reuse CSS if defining styles 'useStyles' would be separate from defining css class?
|
@jEnbuska We have the |
is this enough to get import { useContext } from 'react';
import { ThemeContext } from 'styled-components';
export const useTheme = () => {
const theme = useContext(ThemeContext);
return theme;
}; |
Closed by #2390 |
We should use React hooks once they land in a stable release! Here are a couple first ideas:
useContext
to avoid DevTools bloat withThemeConsumer
componentsuseTheme
hook (see Implement 'useTheme' using Hooks API #2340)Maybe removewithTheme
HOC in favor of the hook?Any other ideas for how we could leverage hooks?
The text was updated successfully, but these errors were encountered: