React Native+Expo가 개발 및 화면 마이그레이션을 시작할 때까지

33956 단어 React NativeReacttech

Expo 설치


npm i -g expo-cli

React Native 프로젝트 작성


expo init my-first-react-native-app

✔ Choose a template: › blank (TypeScript)  same as blank but with TypeScript configuration
- cd my-first-react-native-app
- yarn start # you can open iOS, Android, or web from here, or run them directly with the commands below.
- yarn android
- yarn ios
- yarn web

구축 서버 시작 응용 프로그램 시작


주석
npm start
Developer tools running on http://localhost:19002을 표시한 후 브라우저에서 http://localhost:19002를 엽니다.
iOS 에뮬레이터를 이동하는 동안 다음 오류가 발생했을 때
› Opening on iOS...
xcrun exited with non-zero code: 2
An error was encountered processing the command (domain=NSPOSIXErrorDomain, code=2):
Unable to boot device because we cannot determine the runtime bundle.
No such file or directory
의 대응은 누르기npm start→키보드i를 누르면 사라진다.
Xcode 메뉴 시작 -> Open Developer Tool->Simultator로 시뮬레이터를 시작하면 시뮬레이터 메뉴의 Device->Erase all contentent and settings로 설정을 지웁니다.
xcode가 업데이트되면 expo로 iOS 에뮬레이터를 시작할 수 없습니다.

React Native Paper 설정


Material Design을 따르는 React Native용 UI 라이브러리
npm i react-native-paper
는 루트 디렉터리의 babel.config.js를 다음과 같이 수정합니다.
babel.config.js
module.exports = function(api) {
  api.cache(true);
  return {
    presets: ['babel-preset-expo'],
    env: {
      production: {
        plugins: ['react-native-paper/babel']
      }
    }
  };
};

샘플 이동


지금까지 제작된 환경을 사용해 아래의 화면을 돌려보자.

제작된 것은 다음과 같은 3개다.
  • App.tsx
  • lib/components/Main.tsx
  • lib/components/MyCard.tsx
  • App.tsx
    import { Provider as PaperProvider } from 'react-native-paper'
    import Main from './lib/components/Main'
    
    export default function App() {
      return (
        <PaperProvider>
          <Main />
        </PaperProvider>
      )
    }
    
    lib/components/Main.tsx
    import React from 'react'
    import { Button, Headline, Title } from 'react-native-paper'
    import { SafeAreaView, ScrollView } from 'react-native'
    import MyCard from './MyCard'
    
    const Main = () => (
      <SafeAreaView>
        <ScrollView>
          <Headline
            style={{
              margin: 15,
            }}
          >
            色んなパーツをごちゃまぜ
          </Headline>
          <Title
            style={{
              margin: 15,
            }}
          >
            タイトルだよ〜
          </Title>
          <Button
            mode={'contained'}
            style={{
              margin: 30,
            }}
          >
            containedなボタン
          </Button>
          <MyCard />
        </ScrollView>
      </SafeAreaView>
    )
    
    export default Main
    
    lib/components/MyCard.tsx
    import * as React from 'react'
    import { Avatar, Button, Card, Title, Paragraph } from 'react-native-paper'
    import { ReactNode } from 'react'
    
    const LeftContent = (props: ReactNode) => <Avatar.Icon {...props} icon="folder" />
    
    const MyCard = () => (
      <Card
        style={{
          margin: 20,
        }}
      >
        <Card.Title title="Card Title" subtitle="Card Subtitle" left={LeftContent} />
        <Card.Content>
          <Title>Card title</Title>
          <Paragraph>Card content</Paragraph>
        </Card.Content>
        <Card.Cover source={{ uri: 'https://picsum.photos/700' }} />
        <Card.Actions>
          <Button>Cancel</Button>
          <Button>Ok</Button>
        </Card.Actions>
      </Card>
    )
    
    export default MyCard
    
    
    여기까지만져보면리액트+스위프트UI=리액트나티브의이미지를준다.
    React와 SwiftUI 두 가지 경험이 있다면 쉽게 포착할 수 있을 것 같다.

    화면 이동 실현


    베이스 라이브러리를 설치합니다.
    npm i @react-navigation/native
    
    expo install react-native-gesture-handler react-native-reanimated react-native-screens react-native-safe-area-context @react-native-community/masked-view
    

    화면 전환 모드(Stack Navigator)를 좌우로 이동합니다.


    버튼 오른쪽→← 왼쪽과 화면을 전환하는 화면의 제작 방법.
    npm i @react-navigation/stack
    
    초기 화면

    버튼을 클릭하여 이동합니다.

    ※ 신경쓰지 마세요Disconnected from Metro.
    코드를 만지작거리는 것은 아래 세 개의 파일이다.
  • App.tsx
  • lib/components/HomeScreen.tsx
  • lib/components/DetailScreen.tsx
  • App.tsx
    import 'react-native-gesture-handler'
    import { NavigationContainer } from '@react-navigation/native'
    import HomeScreen from './lib/components/HomeScreen'
    import { createStackNavigator } from '@react-navigation/stack'
    import DetailScreen from './lib/components/DetailScreen'
    
    export type RootStackParamList = {
      Home: undefined
      Detail: undefined
    }
    
    const Stack = createStackNavigator()
    export default function App() {
      return (
        <NavigationContainer>
          <Stack.Navigator initialRouteName={'Home'}>
            <Stack.Screen name={'Home'} component={HomeScreen} />
            <Stack.Screen name={'Detail'} component={DetailScreen} />
          </Stack.Navigator>
        </NavigationContainer>
      )
    }
    
    lib/components/HomeScreen.tsx
    import * as React from 'react'
    import { Text, View, Button } from 'react-native'
    import { useNavigation } from '@react-navigation/native'
    import { StackNavigationProp } from '@react-navigation/stack'
    import { RootStackParamList } from '../../App'
    
    type homeScreenProp = StackNavigationProp<RootStackParamList, 'Home'>
    const HomeScreen = () => {
      const navigation = useNavigation<homeScreenProp>()
      return (
        <View
          style={{
            flex: 1,
            alignItems: 'center',
            justifyContent: 'center',
          }}
        >
          <Text>ホーム画面</Text>
          <Button title={'詳細へ'} onPress={() => navigation.navigate('Detail')} />
        </View>
      )
    }
    
    export default HomeScreen
    
    
    lib/components/DetailScreen.tsx
    import * as React from 'react'
    import { View, Text, Button } from 'react-native'
    import { useNavigation } from '@react-navigation/native'
    
    const DetailScreen = () => {
      const navigation = useNavigation()
      return (
        <View
          style={{
            flex: 1,
            alignItems: 'center',
            justifyContent: 'center',
          }}
        >
          <Text>詳細画面</Text>
          <Button title={'ホームへ'} onPress={() => navigation.goBack()} />
        </View>
      )
    }
    
    export default DetailScreen
    
    

    참고 자료


    Hello React Navigation

    오류 대응


    아래navigation.navigate 중...
    <Button title={"詳細へ"} onPress={() => navigation.navigate("Detail")} />
    
    다음 오류 발생
    TS2345: Argument of type 'string' is not assignable to parameter of type '{ key: string; params?: undefined; merge?: boolean | undefined; } | { name: never; key?: string | undefined; params: never; merge?: boolean | undefined; }'.
    
    이 StackOverflow를 참조하여 제거했습니다.
    navigation.navigate('Home') showing some error in typescript

    탭의 전환 모드(Tab Navigator)


    npm i @react-navigation/bottom-tabs
    

    수정은 App.tsx로 제한됩니다.
    App.tsx
    import 'react-native-gesture-handler'
    import { NavigationContainer } from '@react-navigation/native'
    import HomeScreen from './lib/components/HomeScreen'
    + import { createBottomTabNavigator } from '@react-navigation/bottom-tabs'
    import DetailScreen from './lib/components/DetailScreen'
    
    export type RootStackParamList = {
      Home: undefined
      Detail: undefined
    }
    
    + const Tab = createBottomTabNavigator()
    export default function App() {
      return (
        <NavigationContainer>
    +      <Tab.Navigator initialRouteName={'Home'}>
    +        <Tab.Screen name={'Home'} component={HomeScreen} />
    +        <Tab.Screen name={'Detail'} component={DetailScreen} />
    +      </Tab.Navigator>
        </NavigationContainer>
      )
    }
    

    좋은 웹페이지 즐겨찾기