1、Rn脚手架的选择
前两章我们探索了rn的一些基础理论架构知识,那么现在让我们去进入正题。
现在主流的脚手架有两种React Native CLI和Expo Cli
React Native CLI是由 Facebook 创建的。这个脚手架有三个部分:原生iOS和Android,以及JavaScript。用这个的话你需要下载 Xcode 和 Android Studio。它主要优点之一是它的灵活性。我们可以在原生模块上下载依赖或者写一些代码。但是,它其实对我们的原生开发能力是有一些要求的。
Expo Cli的话其实是一套整体(Expo)架构的一部分。expo其实是一个react app的框架和平台,它集成了打包、发布、测试,当然最重要的是它对于原生能力要求会低一些,我们通常只用在js中就能快速开发和迭代。
那么Expo框架包含了哪些部分那?
* Expo CLI: 一个命令行工具,可以创建项目模版,然后运行、构建和更新它们。
* Expo Go: 一个Android和iOS应用程序,可以直接在设备上运行你的项目(无需编译和签名),并且可以整个团队中一起共享你的项目开发。
* Expo Snack: 浏览器上的playground,就在线玩点小功能。
* Expo App Servieces(ESA): Expo的云服务。
Expo有很多的现成的功能,但是它也对项目施加了限制。我们不能手动连接自定义库到native上,我们通常都直接使用Expo cli提供的库就可以了。其实这就是为了一个版本的兼容性和降低门槛(就是不想调原生),Expo强制帮我们节约这个时间。
简单的说,就是它对没原生能力的同学比较友好。
2、实战
2.1、简单跑一下项目
先下脚手架 npm install -g expo-cli
然后在你的目录下,跑expo init projectName,选第一个就行。

命令行要科学上下网不然项目下载会很慢。

然后我们就可以开始我们的项目实战了。
yarn start

紧接着就轮到Expo Go,它是一个移动端的app,安卓和ios都可以直接下。
我就以ios为例,当你注册账号后,用你ios的相机直接扫这个二维码,然后会在expo go中打开项目,就像这样。

然后打开项目看到已经启动了

并且当我们在编辑器中修改了代码也是可以热更新的,可以看到它其实并不像我们传统rn项目中,还有android和ios目录,他完全就是我们的js代码。

2.2、如何使用外部依赖包
因为后面的所有文章都会有关于raact-navigation导航的内容,所以我们先来尝试下载它。
yarn add @react-navigation/native @react-navigation/native-stack
```
然后我们用`expo`来下载依赖
```java
expo install react-native-screens react-native-safe-area-context
```
我们看到这是不是很迷,就科普一下其实这里就是`expo`帮你处理了一些`rn`的常用包,你的一些三方依赖是在`expo-go`里,但很多时候我们并不知道三方包到底能不能用,我们直接去`rn`的三方包[网站](https://link.juejin.cn?target=https%3A%2F%2Freactnative.directory%2F)去搜索,然后筛选一下,可以看到还是挺多的。而`expo`其实不仅可以加载三方包,本身也为你提供了很多不错的`sdk`,比如`相机`、`音频`、`推送`、`人脸识别`等(但我们其实现在这种开发模式是`expo`的`dev`模式,如果你想引入一些并不支持`expo`的包可以到`dev build`的模式,就也可以定制化的原生操作)。

。
那么我们直接来看一下`react-navigation`的使用。
`app.js`是这样的
```js
import { NavigationContainer } from '@react-navigation/native'
import { createNativeStackNavigator } from '@react-navigation/native-stack'
import Home from './src/pages/Home'
import Settings from './src/pages/Settings'
const Stack = createNativeStackNavigator()
export default function App() {
return (
<NavigationContainer>
<Stack.Navigator>
<Stack.Screen name="Home" component={Home} />
<Stack.Screen name="Settings" component={Settings} />
</Stack.Navigator>
</NavigationContainer>
)
}
```
`createNativeStackNavigator()`是一个设置你的导航的函数。它返回一个具有两个属性的对象,即屏幕组件和导航器组件,它们用于配置我们的导航。
对于`screen`这个组件,它的`name`可以理解为这个组件的`key`或者说组件的映射,然后`compenent`则是要渲染的`组件`,而在上述的代码中会默认渲染`Home`当打开`app`的时候。
```js
import { View, Text, Button, StatusBar } from 'react-native'
import styles from './styles'
export default function Home({ navigation }) {
return (
<View style={styles.container}>
<StatusBar barStyle="dark-content" />
<Text>首页</Text>
<Button title="Settings" onPress={() => navigation.navigate('Settings')} />
</View>
)
}
```
`Home`

而当按`settings`的时候,会定向到`Settings`这个屏幕,而`navigation`这个函数是通过`screen`传递给我们的。

而我们看到`Settings`这个组件,发现它是不是跟`Home`有些许不同,没错他上面有个导航栏,这里显示了组件名称和返回上一级的按钮,而它其实是`react-navigation`所提供的`navigation bar`。
```js
import { View, Text, Button, StatusBar } from 'react-native'
import styles from './styles'
export default function Settings({ navigation }) {
return (
<View style={styles.container}>
<StatusBar barStyle="dark-content" />
<Text>设置</Text>
<Button title="Home" onPress={() => navigation.navigate('Home')} />
</View>
)
}
```
接下来我们看一下如何传参,如下
```js
import { View, Text, Button, StatusBar } from 'react-native'
import styles from './styles'
export default function Settings({ navigation }) {
return (
<View style={styles.container}>
<StatusBar barStyle="dark-content" />
<Text>设置</Text>
<Button title="Home" onPress={() => navigation.navigate('Home',{title: "我好烦"})} />
</View>
)
}
```
其实就只是第二个参数,带过去就可以,而同样接受的地方,也可以从`props`中把`route`解构出来,直接去使用。
```js
import { View, Text, Button, StatusBar } from 'react-native'
import styles from './styles'
export default function Home({ navigation, route }) {
const { title } = route.params;
return (
<View style={styles.container}>
<StatusBar barStyle="dark-content" />
<Text>首页</Text>
<Button title="Settings" onPress={() => navigation.navigate('Settings')} />
</View>
)
}
```
那么我们如果有时候要配置`navigation header`那,就需要再配置下`option`。
```javascript
import { NavigationContainer } from '@react-navigation/native'
import { createNativeStackNavigator } from '@react-navigation/native-stack'
import { Button } from 'react-native'
import Home from './src/pages/Home'
import Settings from './src/pages/Settings'
const Stack = createNativeStackNavigator()
export default function App() {
return (
<NavigationContainer>
<Stack.Navigator>
<Stack.Screen name="Home" component={Home} />
<Stack.Screen
name="Settings"
component={Settings}
options={route => ({
headerRight: () => <Button title="test" />,
})}
/>
</Stack.Navigator>
</NavigationContainer>
)
}
```

最后我们来试一下,`tabbar`和`drawer`。需要先下载`npm`依赖和`expo`依赖。
```java
yarn add @react-navigation/bottom-tabs @react-navigation/drawer
expo install react-native-gesture-handler react-native-reanimated
```
然后再`babel.config.js`里,加入插件配置。
```ini
module.exports = function (api) {
api.cache(true);
return {
presets: ["babel-preset-expo"],
plugins: ["react-native-reanimated/plugin"],
};
};
```
此时我们的`App.js`文件是这样的
```javascript
import { NavigationContainer } from '@react-navigation/native'
import { createDrawerNavigator } from '@react-navigation/drawer'
import { createBottomTabNavigator } from '@react-navigation/bottom-tabs'
import { Platform } from 'react-native'
import Home from './Home'
import News from './News'
import Settings from './Settings'
const Tab = createBottomTabNavigator()
const Drawer = createDrawerNavigator()
export default function App() {
return (
<NavigationContainer>
{Platform.OS === 'ios' && (
<Tab.Navigator>
<Tab.Screen name="Home" component={Home} />
<Tab.Screen name="News" component={News} />
<Tab.Screen name="Settings" component={Settings} />
</Tab.Navigator>
)}
{Platform.OS == 'android' && (
<Drawer.Navigator>
<Drawer.Screen name="Home" component={Home} />
<Drawer.Screen name="News" component={News} />
<Drawer.Screen name="Settings" component={Settings} />
</Drawer.Navigator>
)}
</NavigationContainer>
)
}
```
你使用的现在是`tabbar`和`drwaer`的导航了,而不是由`createNativeStack`创建的。然后其中的`Platform`是用来区别`安卓ios`的。
`Home`
```js
import React from 'react'
import { View, Text } from 'react-native'
import styles from './styles'
export default function Home() {
return (
<View style={styles.container}>
<Text>Home Content</Text>
</View>
)
}
```
`ios`

`安卓`

# 3、结束
这一节主要讲一下`RN`入门的脚手架学习,和关于路由导航,比较简单一点,em如果大家有问题,或者想学点更深入的东西直接看[沸点](https://juejin.cn/user/400646714977431/pins)加我就好,免费课就是为了让大家学懂跨端框架。