React native elements with Stylesheet.create

Viewed 4042

I am trying to use react-native-elements with my React-Native app.

I have a central js file with theme details which are being injected using ThemeProvider as explained here - https://react-native-elements.github.io/react-native-elements/docs/customization.html

However, when I try to use the passed theme in a component's stylesheet.create method, I am getting an error. What am I doing wrong? -

import React from 'react';
import {View, StyleSheet} from 'react-native';
import {Text, withTheme} from 'react-native-elements';

const Header = props => {
  const {theme} = props;

  return (
    <View style={styles.container}>
      <Text>Home</Text>
    </View>
  );
};
const styles = StyleSheet.create({
  container: {
    width: '100%',
    backgroundColor: theme.container.backgroundColor,//**** Getting error here stating that theme is not defined
    shadowRadius: 1.5,
    elevation: 2,
    shadowColor: 'rgb(0,0,0)',
    shadowOpacity: 0.4,
    shadowOffset: {width: 0, height: 2.5},
  },
});

export default withTheme(Header);

Please let me know if I can provide further details.


Update:

Thanks to the suggestion provided below @Sebastian Berglönn , I was able to get it parameterised without exporting to a different file by doing this -

const Header = props => {
  const {theme} = props;

  return (
    <View style={styles(theme).container}>
      <Text>Home</Text>
    </View>
  );
};
const styles = theme =>
  StyleSheet.create({
    container: {
      width: '100%',
      backgroundColor: theme.container.backgroundColor,
      shadowRadius: 1.5,
      elevation: 2,
      shadowColor: 'rgb(0,0,0)',
      shadowOpacity: 0.4,
      shadowOffset: {width: 0, height: 2.5},
    },
  });
5 Answers

From looking the code theme is defined inside the Header Component,So it is showing theme is undefined.

To apply backgroundColor from the theme you can do as follows:

const Header = props => {
  const {theme} = props;

  return (
    <View style={[styles.container,{backgroundColor: theme.container.backgroundColor}]}>
      <Text>Home</Text>
    </View>
  );
};

and don't forget to remove the backgroundColor from StyleSheet.

const styles = StyleSheet.create({
  container: {
    width: '100%',
    //backgroundColor: theme.container.backgroundColor,
    shadowRadius: 1.5,
    elevation: 2,
    shadowColor: 'rgb(0,0,0)',
    shadowOpacity: 0.4,
    shadowOffset: {width: 0, height: 2.5},
  },
});

I can suggest you a cleaner way using functions with the Stylesheet. The approach is similar to to the suggestion given on the first topic but instead of using a global stylesheet var, we'll use a variable only on the needed style:

  container: theme => ({
      flex: 1,
      backgroundColor: theme.colors.backgroundPrimary
   }),

And on your view, the usage is pretty clean too:

<View style={styles.container(theme)}>

However, both solutions are working like a charm, choose the one which is matching the most with your needs :)

Inside the Provider or children of a Provided component, you can do something like this, by using HOC:

import React from 'react';
import {View, StyleSheet} from 'react-native';
import {Text, withTheme} from 'react-native-elements';

const Header = props => {
  const {theme} = props;

  return (
    <View style={styles(theme).container}> // --> Here styles called as a function
      <Text>Home</Text>
    </View>
  );
};

const styles = theme => StyleSheet.create({
  container: {
      width: '100%',
      backgroundColor: theme.container.backgroundColor,
      shadowRadius: 1.5,
      elevation: 2,
      shadowColor: 'rgb(0,0,0)',
      shadowOpacity: 0.4,
      shadowOffset: {width: 0, height: 2.5},
    }
});

export default withTheme(Header, styles);

Reusable theme solve for react native styles sheet and theme ✅

I think it help everybody (spent 2 hour for good work of types)


const getStylesHook = <T extends ReturnType<typeof StyleSheet.create>>(
  cb: (theme: IMyTheme) => T,
): (() => {styles: T}) => {
  return () => {
    const theme = useTheme();
    return useMemo(
      () => ({
        styles: cb(theme),
      }),
      [theme.dark],
    );
  };
};

export default getStylesHook;

///

const useStyles = getStylesHook((theme) => ({
   container: {backgroundColor: 'green'}
})

///

const {styles} = useStyles();


Pass theme to StyleSheet from the style props and use useContext to handle dark/light mode

my code:

const Notifications = (props: NotificationsProps) => {
    const dispatch = useDispatch()
    const theme = useContext(themeContext)
    return (
        <View style={styles(theme).center}>
            <Text style={styles(theme).text}>This is the Notifications screen</Text>
            <Button title="Next" onPress={() => dispatch(setIsOnBoardingDone(true))} />
        </View>
    );
};

const styles = (theme: any) => StyleSheet.create({
    center: {
        flex: 1,
        justifyContent: "center",
        alignItems: "center",
        textAlign: "center",
        backgroundColor: theme.code_black
    },
    text: {
        color: theme.white
    }
});
Related