Skip to content

样式继承、复用、全局样式

React Native 核心基础

在 React Native 中,样式的继承、复用和全局样式管理是提高代码可维护性和一致性的重要手段。本文将介绍如何有效地管理和复用样式。

1. 样式继承

基本概念

与 CSS 不同,React Native 中的样式不会自动继承。每个组件的样式都是独立的,需要显式设置。

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

export default function StyleInheritanceExample() {
  return (
    <View style={styles.container}>
      <Text style={styles.parentText}>Parent Text</Text>
      <View style={styles.childContainer}>
        <Text style={styles.childText}>Child Text</Text>
      </View>
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    padding: 20,
  },
  parentText: {
    fontSize: 20,
    color: '#333',
    fontWeight: 'bold',
  },
  childContainer: {
    marginTop: 20,
    padding: 10,
    backgroundColor: '#f0f0f0',
  },
  childText: {
    // 不会继承 parentText 的样式,需要显式设置
    fontSize: 16,
    color: '#666',
  },
});

实现样式继承

虽然 React Native 不支持自动样式继承,但可以通过样式组合来实现类似的效果。

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

// 基础文本样式
const baseTextStyle = StyleSheet.create({
  base: {
    fontSize: 16,
    lineHeight: 24,
  },
});

export default function StyleInheritanceExample() {
  return (
    <View style={styles.container}>
      <Text style={[baseTextStyle.base, styles.title]}>Title Text</Text>
      <Text style={[baseTextStyle.base, styles.subtitle]}>Subtitle Text</Text>
      <Text style={[baseTextStyle.base, styles.body]}>Body Text</Text>
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    padding: 20,
  },
  title: {
    fontSize: 24,
    fontWeight: 'bold',
    color: '#333',
    marginBottom: 10,
  },
  subtitle: {
    fontSize: 18,
    fontWeight: '500',
    color: '#666',
    marginBottom: 10,
  },
  body: {
    color: '#999',
  },
});

2. 样式复用

样式对象复用

将常用的样式定义为单独的对象,然后在多个组件中复用。

jsx
import React from 'react';
import { View, Text, StyleSheet, TouchableOpacity } from 'react-native';

// 可复用的样式
const commonStyles = StyleSheet.create({
  button: {
    paddingHorizontal: 20,
    paddingVertical: 10,
    borderRadius: 8,
    alignItems: 'center',
  },
  buttonText: {
    fontSize: 16,
    fontWeight: '500',
    color: '#fff',
  },
  card: {
    backgroundColor: '#fff',
    padding: 16,
    borderRadius: 8,
    shadowColor: '#000',
    shadowOffset: {
      width: 0,
      height: 2,
    },
    shadowOpacity: 0.1,
    shadowRadius: 3.84,
    elevation: 5,
    marginBottom: 16,
  },
});

export default function StyleReuseExample() {
  return (
    <View style={styles.container}>
      <View style={commonStyles.card}>
        <Text style={styles.cardTitle}>Card Title</Text>
        <Text style={styles.cardText}>Card content goes here</Text>
        <TouchableOpacity style={[commonStyles.button, styles.primaryButton]}>
          <Text style={commonStyles.buttonText}>Primary Button</Text>
        </TouchableOpacity>
      </View>
      <View style={commonStyles.card}>
        <Text style={styles.cardTitle}>Another Card</Text>
        <Text style={styles.cardText}>More card content</Text>
        <TouchableOpacity style={[commonStyles.button, styles.secondaryButton]}>
          <Text style={commonStyles.buttonText}>Secondary Button</Text>
        </TouchableOpacity>
      </View>
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    padding: 20,
    backgroundColor: '#f5f5f5',
  },
  cardTitle: {
    fontSize: 18,
    fontWeight: 'bold',
    marginBottom: 8,
  },
  cardText: {
    fontSize: 14,
    color: '#666',
    marginBottom: 16,
  },
  primaryButton: {
    backgroundColor: '#4CAF50',
  },
  secondaryButton: {
    backgroundColor: '#2196F3',
  },
});

样式工具函数

创建样式工具函数,根据不同的参数生成样式。

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

// 生成按钮样式的工具函数
const getButtonStyle = (type = 'primary', size = 'medium') => {
  const styles = {
    container: {
      borderRadius: 8,
      alignItems: 'center',
      justifyContent: 'center',
    },
    text: {
      fontWeight: '500',
    },
  };

  // 类型样式
  switch (type) {
    case 'primary':
      styles.container.backgroundColor = '#4CAF50';
      styles.text.color = '#fff';
      break;
    case 'secondary':
      styles.container.backgroundColor = '#2196F3';
      styles.text.color = '#fff';
      break;
    case 'danger':
      styles.container.backgroundColor = '#f44336';
      styles.text.color = '#fff';
      break;
    default:
      styles.container.backgroundColor = '#4CAF50';
      styles.text.color = '#fff';
  }

  // 尺寸样式
  switch (size) {
    case 'small':
      styles.container.paddingHorizontal = 12;
      styles.container.paddingVertical = 6;
      styles.text.fontSize = 14;
      break;
    case 'medium':
      styles.container.paddingHorizontal = 20;
      styles.container.paddingVertical = 10;
      styles.text.fontSize = 16;
      break;
    case 'large':
      styles.container.paddingHorizontal = 28;
      styles.container.paddingVertical = 14;
      styles.text.fontSize = 18;
      break;
    default:
      styles.container.paddingHorizontal = 20;
      styles.container.paddingVertical = 10;
      styles.text.fontSize = 16;
  }

  return styles;
};

export default function StyleUtilityExample() {
  const primaryButtonStyle = getButtonStyle('primary', 'medium');
  const secondaryButtonStyle = getButtonStyle('secondary', 'small');
  const dangerButtonStyle = getButtonStyle('danger', 'large');

  return (
    <View style={styles.container}>
      <View style={[styles.button, primaryButtonStyle.container]}>
        <Text style={primaryButtonStyle.text}>Primary Button</Text>
      </View>
      <View style={[styles.button, secondaryButtonStyle.container]}>
        <Text style={secondaryButtonStyle.text}>Secondary Button</Text>
      </View>
      <View style={[styles.button, dangerButtonStyle.container]}>
        <Text style={dangerButtonStyle.text}>Danger Button</Text>
      </View>
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
    padding: 20,
  },
  button: {
    marginBottom: 16,
  },
});

3. 全局样式

创建全局样式文件

创建一个全局样式文件,定义应用中使用的通用样式。

jsx
// styles/global.js
import { StyleSheet, Platform } from 'react-native';

// 颜色常量
export const Colors = {
  primary: '#4CAF50',
  secondary: '#2196F3',
  danger: '#f44336',
  warning: '#FFC107',
  info: '#00BCD4',
  light: '#f5f5f5',
  dark: '#333',
  gray: '#999',
  white: '#fff',
  black: '#000',
};

// 字体大小
export const FontSizes = {
  xs: 12,
  sm: 14,
  md: 16,
  lg: 18,
  xl: 20,
  xxl: 24,
  xxxl: 32,
};

// 间距
export const Spacing = {
  xs: 4,
  sm: 8,
  md: 16,
  lg: 24,
  xl: 32,
  xxl: 48,
};

// 边框半径
export const BorderRadius = {
  sm: 4,
  md: 8,
  lg: 12,
  xl: 16,
  round: 9999,
};

// 阴影
export const Shadows = {
  sm: {
    shadowColor: '#000',
    shadowOffset: {
      width: 0,
      height: 1,
    },
    shadowOpacity: 0.18,
    shadowRadius: 1.0,
    elevation: 1,
  },
  md: {
    shadowColor: '#000',
    shadowOffset: {
      width: 0,
      height: 2,
    },
    shadowOpacity: 0.20,
    shadowRadius: 1.41,
    elevation: 2,
  },
  lg: {
    shadowColor: '#000',
    shadowOffset: {
      width: 0,
      height: 4,
    },
    shadowOpacity: 0.25,
    shadowRadius: 3.84,
    elevation: 5,
  },
};

// 全局样式
export const GlobalStyles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: Colors.light,
  },
  safeArea: {
    flex: 1,
    backgroundColor: Colors.white,
  },
  center: {
    justifyContent: 'center',
    alignItems: 'center',
  },
  row: {
    flexDirection: 'row',
  },
  spaceBetween: {
    justifyContent: 'space-between',
  },
  alignCenter: {
    alignItems: 'center',
  },
  title: {
    fontSize: FontSizes.xl,
    fontWeight: 'bold',
    color: Colors.dark,
    marginBottom: Spacing.md,
  },
  subtitle: {
    fontSize: FontSizes.lg,
    fontWeight: '500',
    color: Colors.gray,
    marginBottom: Spacing.sm,
  },
  body: {
    fontSize: FontSizes.md,
    color: Colors.dark,
    lineHeight: FontSizes.md * 1.5,
  },
  card: {
    backgroundColor: Colors.white,
    borderRadius: BorderRadius.md,
    padding: Spacing.md,
    ...Shadows.md,
    marginBottom: Spacing.md,
  },
  button: {
    paddingHorizontal: Spacing.lg,
    paddingVertical: Spacing.md,
    borderRadius: BorderRadius.md,
    alignItems: 'center',
    justifyContent: 'center',
  },
  buttonText: {
    fontSize: FontSizes.md,
    fontWeight: '500',
    color: Colors.white,
  },
  input: {
    borderWidth: 1,
    borderColor: Colors.gray,
    borderRadius: BorderRadius.md,
    paddingHorizontal: Spacing.md,
    paddingVertical: Spacing.sm,
    fontSize: FontSizes.md,
    color: Colors.dark,
  },
});

使用全局样式

在组件中导入并使用全局样式。

jsx
import React from 'react';
import { View, Text, StyleSheet, TouchableOpacity, TextInput } from 'react-native';
import { GlobalStyles, Colors, Spacing } from '../styles/global';

export default function GlobalStylesExample() {
  return (
    <View style={GlobalStyles.container}>
      <View style={[GlobalStyles.card, styles.card]}>
        <Text style={GlobalStyles.title}>Global Styles Example</Text>
        <Text style={GlobalStyles.subtitle}>This is a subtitle</Text>
        <Text style={GlobalStyles.body}>
          This is an example of how to use global styles in React Native.
        </Text>
        <TextInput
          style={[GlobalStyles.input, styles.input]}
          placeholder="Enter text here"
        />
        <TouchableOpacity style={[GlobalStyles.button, styles.primaryButton]}>
          <Text style={GlobalStyles.buttonText}>Primary Button</Text>
        </TouchableOpacity>
      </View>
    </View>
  );
}

const styles = StyleSheet.create({
  card: {
    margin: Spacing.md,
  },
  input: {
    marginBottom: Spacing.md,
  },
  primaryButton: {
    backgroundColor: Colors.primary,
  },
});

4. 主题系统

创建主题

创建一个主题系统,支持浅色和深色模式。

jsx
// styles/theme.js
import { ColorSchemeName } from 'react-native';

// 浅色主题
const lightTheme = {
  colors: {
    primary: '#4CAF50',
    secondary: '#2196F3',
    background: '#f5f5f5',
    surface: '#ffffff',
    text: '#333333',
    border: '#e0e0e0',
    error: '#f44336',
  },
};

// 深色主题
const darkTheme = {
  colors: {
    primary: '#81C784',
    secondary: '#64B5F6',
    background: '#121212',
    surface: '#1E1E1E',
    text: '#ffffff',
    border: '#333333',
    error: '#EF5350',
  },
};

// 根据系统主题返回对应的主题
export const getTheme = (colorScheme: ColorSchemeName = 'light') => {
  return colorScheme === 'dark' ? darkTheme : lightTheme;
};

// 导出类型
export type Theme = typeof lightTheme;

使用主题

在组件中使用主题。

jsx
import React, { useColorScheme } from 'react';
import { View, Text, StyleSheet } from 'react-native';
import { getTheme } from '../styles/theme';

export default function ThemedExample() {
  const colorScheme = useColorScheme();
  const theme = getTheme(colorScheme);

  return (
    <View style={[styles.container, { backgroundColor: theme.colors.background }]}>
      <Text style={[styles.text, { color: theme.colors.text }]}>
        Themed Text
      </Text>
      <View style={[styles.box, { backgroundColor: theme.colors.surface, borderColor: theme.colors.border }]}>
        <Text style={[styles.boxText, { color: theme.colors.text }]}>
          Themed Box
        </Text>
      </View>
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    padding: 20,
  },
  text: {
    fontSize: 20,
    marginBottom: 20,
  },
  box: {
    padding: 20,
    borderRadius: 8,
    borderWidth: 1,
  },
  boxText: {
    fontSize: 16,
  },
});

5. 样式管理最佳实践

1. 组织样式文件

将样式文件组织成模块,提高代码的可维护性。

styles/
  ├── global.js         # 全局样式
  ├── theme.js          # 主题系统
  ├── components.js     # 组件样式
  └── screens/          # 页面样式
      ├── HomeScreen.js
      ├── ProfileScreen.js
      └── ...

2. 使用样式常量

定义颜色、间距、字体大小等常量,确保应用风格一致。

3. 避免内联样式

尽量避免使用内联样式,使用 StyleSheet.create 定义样式。

4. 合理使用样式组合

使用数组组合多个样式,提高样式的复用性。

5. 考虑平台差异

使用 Platform.select 为不同平台设置不同的样式。

6. 使用第三方样式库

考虑使用第三方样式库,如 styled-componentsemotion,提高开发效率。

6. 常见问题与解决方案

问题 1:样式冲突

问题:样式之间发生冲突。

解决方案

  • 确保样式的优先级正确
  • 使用更具体的样式选择器
  • 避免过度使用 !important

问题 2:样式维护困难

问题:样式文件过大,维护困难。

解决方案

  • 将样式文件拆分为多个模块
  • 使用样式常量和工具函数
  • 建立样式规范

问题 3:主题切换困难

问题:难以实现主题切换。

解决方案

  • 使用主题系统
  • 利用 Context API 提供主题
  • 考虑使用第三方主题库

问题 4:性能问题

问题:样式导致性能问题。

解决方案

  • 避免在渲染过程中创建新的样式对象
  • 使用 StyleSheet.create 定义样式
  • 避免过度使用样式继承

7. 总结

在 React Native 中,有效的样式管理是创建高质量应用的关键。通过使用样式继承、复用和全局样式,可以提高代码的可维护性和一致性。

在实际开发中,建议:

  1. 组织样式文件,提高代码可维护性
  2. 使用样式常量,确保风格一致
  3. 合理使用样式组合,提高样式复用性
  4. 建立主题系统,支持深色模式
  5. 避免常见的样式问题

通过掌握这些样式管理技术,你可以创建出更加美观、专业的移动应用界面。

© 2026 编程马·菜鸟教程 版权所有