如何在React Native中引入CSS和字体

1,711 阅读2分钟

为什么要在RN中写CSS

如果只是开发的平台目标只定位在Android和IOS,那么是不需要和CSS打交道的,利用RN提供的StyleSheet.create才是唯一正确的选择。之所以需要在RN项目中引入CSS,是因为有的项目是利用React Native Web,通过RN的一套项目,编译出另一套在Web端运行的实例。虽然RNW可以将几乎所有的StyleSheet的内容都自动映射成对应的Web元素的CSS,但是总有个别情况,需要用一些全局的CSS复写映射后的CSS。

首选StyleSheet来写Web的Style

在创建了某个RN组件之后,一定要通过StyleSheet.create来创建它的style,因为这样的style,在被RNW转换后,可以生成用来定位和复写的class。请参考下面的截图:

image.png

这些class的名字,虽然看起来像是随机生成的,但是只要RN的组件结构和style不再发生变化,它们要是不会再变化的,所以完全可以通过class来定位Web元素进行复写。但是除非特殊情况,不得不这么做,否则还是建议通过StyleSheet来设置style,而不是CSS复写的方式。

可以利用Platform.OS来针对Native和Web项目,使用不同的Style,从而达到微调Web Style的目的。参考如下代码:

const styles = StyleSheet.create({
    buttonContainer: {
    ...(Platform.OS === 'web' ? {width: 50, marginLeft: 10} : { width: 20 })
  }
})

RN项目中CSS应该少量并集中

在RN项目中引入CSS,是为了一些极其特殊的情况或者一些基础元素的通用设置,不应该作为一个普遍的解决兼容Web端样式的方式。所以,不应该在RN项目中大量引入CSS和其他的预编译样式文件,甚至就不应该引用。当然,这种武断的结论,我不能保证它是绝对正确的,但是在我个人的项目中,我是把所有的CSS都放到了RN项目中Web实例的入口index.html中的里了。请参考如下代码:

    <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>My App</title>
    <style>
      #app-root {
        display: flex;
        flex: 1 1 100%;
        height: 100vh;
      }
      input {
        outline: none;
      }
      textarea{
        outline: none;
      }
      .css-view-175oi2r.r-pointerEvents-105ug2t {
        padding: 20px;
      }
    </style>
  </head>

RN项目中引入字体

直接上代码,清楚明了:

// index.web.js
/* eslint-disable import/no-import-module-exports */
import { AppRegistry } from 'react-native'
import Ionicons from 'react-native-vector-icons/Fonts/Ionicons.ttf'
import AntDesign from 'react-native-vector-icons/Fonts/AntDesign.ttf'
import App from './src/App'
import { name as appName } from './app.json'
/* eslint-enable import/no-import-module-exports */

const IoniconsStyles = `
  @font-face {
    src: url(${Ionicons});
    font-family: Ionicons;
  }

  @font-face {
    src: url(${AntDesign});
    font-family: AntDesign;
  }
`

const style = document.createElement('style')
style.type = 'text/css'

if (style.styleSheet) {
  style.styleSheet.cssText = IoniconsStyles
} else {
  style.appendChild(document.createTextNode(IoniconsStyles))
}

document.head.appendChild(style)

if (module.hot) {
  module.hot.accept()
}

AppRegistry.registerComponent(appName, () => App)
AppRegistry.runApplication(appName, {
  initialProps: {},
  rootTag: document.getElementById('app-root')
})

如果有人不知道index.web.js是怎么来的,请参考如何用React Native开发Web应用。这里的重点,是要通过js来把字体文件引入,而不是在index.html中通过style来加载。