In the documentation it says that the styled decorator can be used on class components, but what if we don't want to write out an actual class component such as
@style('BrandButton')
export class BrandButton extends React.PureComponent<any>{}
and instead we wanted to use functional components that will inherit the styles
export const BrandButton = (props:any) => {}
or is this what the withStyles function was intended for. Although this function only seems to grab variables from the theme and doesn't do any custom component mapping itself.
| Package | Version |
| ----------- | ----------- |
| @eva-design/eva | 2.0.0|
| @ui-kitten/components |5.0.0|
and instead we wanted to use functional components
No way to use it with styled function yet. And no way to use same API in future for functional components. I guess we need same thing implemented as hook.
this function only seems to grab variables from the theme
That's what the docs say
Any update on if the hook will be available soon, or we need to implement it ourselves?
UPDATE
I quickly tried a solution and came up with a solution. It works, though I am not sure if this is an optimal way of using a hook.
import { MappingContext } from '@ui-kitten/components/theme/mapping/mappingContext';
import { StyleConsumerService } from '@ui-kitten/components/theme/style/styleConsumer.service';
import { ThemeContext } from '@ui-kitten/components/theme/theme/themeContext';
import React from 'react';
export const useEvaStyled = (
name: string,
sourceProps: Record<string, any>,
) => {
const [interaction, setInteraction] = React.useState([]);
const mappingStyle = React.useContext(MappingContext);
const evaTheme = React.useContext(ThemeContext);
const service = new StyleConsumerService(name, mappingStyle);
const defaultProps = service.createDefaultProps();
const computedProps = { ...defaultProps, ...sourceProps };
const computedStyle = service?.createStyleProp(
computedProps,
mappingStyle,
evaTheme,
interaction,
);
return {
...computedProps,
eva: {
theme: evaTheme,
style: computedStyle,
dispatch: (newInteraction: any) => setInteraction(newInteraction),
},
};
};
use it as follows:
import React from 'react';
import { TouchableOpacity } from 'react-native';
import { useEvaStyled } from '../hooks/useEvaStyled'; // change the path
interface CircleButtonProps {}
export const CircleButton: React.FC<CircleButtonProps> = (props) => {
const { eva, ...otherProps } = useEvaStyled('CircleButton', props);
return <TouchableOpacity {...otherProps} style={eva.style} />;
};
I am in the midts of updating to 5. but since I am using mostly FCs the masking of styled HOC in a decorator doesn't work in my case. Therefore I am trying a hook alternative.
@3kumar Here are some thoughts on your hook. You should try to not return new values each time the hook is executed (i.e. on every render). This could have significant performance impact. My first approach would be to memo basically everything.
This is my version of your hook.
export function useStyled(name: string, sourceProps: Record<string, any>) {
const [interaction, setInteraction] = React.useState([]);
const mappingStyle = useContext(MappingContext);
const evaTheme = useContext(ThemeContext);
const service = useMemo(() => new StyleConsumerService(name, mappingStyle), [name, mappingStyle]);
const defaultProps = useMemo(() => service.createDefaultProps(), [service]);
const computedProps = useMemo(() => ({ ...defaultProps, ...sourceProps }), [defaultProps, sourceProps]);
const computedStyle = useMemo(() => service?.createStyleProp(computedProps, mappingStyle, evaTheme, interaction), [
service,
computedProps,
mappingStyle,
evaTheme,
interaction
]);
return useMemo(
() => ({
...computedProps,
eva: {
theme: evaTheme,
style: computedStyle,
dispatch: (newInteraction: any) => setInteraction(newInteraction)
}
}),
[computedProps, evaTheme, computedStyle]
);
}
Most helpful comment
I am in the midts of updating to 5. but since I am using mostly FCs the masking of styled HOC in a decorator doesn't work in my case. Therefore I am trying a hook alternative.
@3kumar Here are some thoughts on your hook. You should try to not return new values each time the hook is executed (i.e. on every render). This could have significant performance impact. My first approach would be to memo basically everything.
This is my version of your hook.