728x90
반응형

 

이전 포스팅이였던  스택 네비게이션도 한번 확인 해보세요~

 

2022.07.04 - [Mobile/React Native] - React Native_스택 네비게이션 활용 페이지와 컴포넌트 이동

 

React Native_스택 네비게이션 활용 페이지와 컴포넌트 이동

스택 네비게이션이란? 컴포넌트에서 컴포넌트로 이동을 용이하게 해주는 기능이다. 즉 페이지를 이동하는 방법이라고 생각하면된다. 컴포넌트를 이동이라고는 하지만 솔직히 페이지 이동이라

tantangerine.tistory.com

 

 

앱 공유하기 기능 - Share

 

유튜브나 블로그 글 같은 것을 보다 보면 공유하기 버튼을 클릭해서

앱들 간의 다른 사람들과 공유하는 기능을 보실 수 있었을 것입니다.

 

react-nativeShare함수를 사용하면 간편하게 기능을 구현할 수 있습니다

 

 

import { Share } from "react-native"

 

위와 같이 import를 해서 사용합니다

 

Share.share({ message: '내용' });

 

 

share 함수를 사용하면 우리가 흔히 볼 수 있는 공유 창이 나타나고 내용들이 메세지로 전달됩니다.

 

 

import React from 'react';
import { TouchableOpacity,Share } from 'react-native';


export default function DetailPage({navigation,route}) {	
    const share = () => {
        Share.share({
            message:`${tip.title} \n\n ${tip.desc} \n\n ${tip.image}`,
        });
    }
    
    return (
      <TouchableOpacity style={styles.button} onPress={()=>share()}>
        <Text style={styles.buttonText}>
          공유하기
        </Text>
      </TouchableOpacity>
    )
}

 

TouchableOpactiy 컴포넌트에 onPress속성에 share함수만 넣어서 실행하면됩니다.

 그때 실행할 때 인자값으로 공유할 내용을 같이 전달하면 기능 구현은 끝입니다.

 

 

아래와 같이 공유 기능이 노출됩니다

 

공유하기 버튼클릭시 이미지

 

반응형

 

 

공유 전달된 이미지

 

이미지도 지금은 글자로 들어가지만 

<img> 태그를 사용하면 문자로 보낼 경우 이미지를 노출시킬수도 있습니다

 

 


 

앱 외부링크 이동 기능 - Linking 

 

앱에서 외부링크를 여는 방법은 Expo에 제공해주는 라이브러리를 설치하여 

LinkingopenURL 함수를 사용하여 기능 구현을 합니다

 

import React from 'react';
import { TouchableOpacity,Share } from 'react-native';


export default function DetailPage({navigation,route}) {	
    const link = () => {
        Linking.openURL("https://spartacodingclub.kr")
    }
    
    return (
       <TouchableOpacity style={styles.button} onPress={()=>link()}>
         <Text style={styles.buttonText}>
           외부 링크
         </Text>
       </TouchableOpacity>
    )
}

 

정말 위의 코드만 보면 정말 간단하죠?

 

코드를 작성하면서 저 또한  앱에 대한 기능 공부를 복습하게되었습니다

저도 저만의 앱을 만들려고 앱을 공부하고 있습니다

 

아직까지 모험은 끝나지 않았으니까요!!

오늘도 한 발자국 나아갑시다!!

화이팅!!

 

728x90
반응형
728x90
반응형

스택 네비게이션이란?

컴포넌트에서 컴포넌트로 이동을 용이하게 해주는 기능이다.

즉 페이지를 이동하는 방법이라고 생각하면된다.

 

페이지이동에 대한 과정이다

 

컴포넌트를 이동이라고는 하지만 솔직히 페이지 이동이라고 하는것이 맞는 것 같아요.

하지만 컴포넌트 이동이라고 표현하는 것도 코드 구조를 보면 약간은 이해가 갈거예요.

 

왜 그렇냐면 화면에 노출 시킬 페이지를 import하여 Stack.Screen 속성 component에 할당합니다.

모든 페이지를 그렇게 연결하게되면 페이지이동을 간편하게 할 수 있습니다

 

아래의 코드를 보고 다시 한번 더 확인해보아요.

 

 

스택네비게이션의 활용방법

 

라이브러리 설치

yarn add @react-navigation/stack

 

 

/navigation/StackNavigator.js

폴더를 생성하고 파일을 만들어 코드 작성을 합니다.

 

StackNavigator.js

import React from 'react';
import { createStackNavigator } from '@react-navigation/stack';

import DetailPage from '../pages/DetailPage';
import MainPage from '../pages/MainPage';

const Stack = createStackNavigator();

const StackNavigator = () =>{
    return (
         <Stack.Navigator
            screenOptions={{
                headerStyle: {
                    backgroundColor: "white",
                    borderBottomColor: "white",
                    shadowColor: "white",
                    height:100
                },
                headerTitleAlign:'left',
                headerTintColor: "#000",
                headerBackTitleVisible: false
            }}
            
        >
            <Stack.Screen name="MainPage" component={MainPage}/>
            <Stack.Screen name="DetailPage" component={DetailPage}/>
        </Stack.Navigator>
    )
}

export default StackNavigator;

 

 

createStackNavigator() 함수를 변수에 할당하여 변수로 활용합니다.

 

Stack에 저장된 스택 네비게이션에는 몇가지 태그가 존재한다. 그 중에는 Navigator, Screen있습니다.

 

 

Stack.Navigator

Stack.Navigator는 페이지에 헤더가 되는 부분을 스타일링을 해주는 컴포넌트있습니다.

이 컴포넌트에서는 페이지에서 헤더가 별도로 존재하지않아도 공통으로 관리할 수 있습니다.

배경 색깔, 버튼 색깔, 페이지 타이틀, 타이틀 위치 등등

 

 

Stack.Screen

Stack.Screen은 활용하면 페이지를 할당해서 스택 네비게이션 함수를 사용하여

스택 네비게이션에 관리가 용이하다. 그리고 Stack.Screen에 등록됩니다.

모든 페이지들은 navigationrouter 객체를 넘겨받아 사용할 수 있습니다.

 

navigation.setOptions({ title: '메인 페이지' })

- 해당 페이지의 제목을 설정할 수 있습니다.

 

navigation.navigate("DetailPage")

- Stack.screen에서 등록된 속성 name으로 지정하면 페이지로 이동하는 함수입니다.

 

navigation.navigate("DetailPage", { title: '페이지' })

- 페이지를 이동하면서 두번째 인자값의 객체를 이동된 페이지에서 router로 받을 수 있습니다.

 

 

이러한 기능들이 다 사용하여 페이지를 이동시 데이터를 주고 받을 수 있습니다.

그럼 메인 페이지의 코드와 상세 페이지의 코드를 확인해서 어떻게 사용하는지 확인해 보아요!! 

 

 

MainPage.js

import React,{useState,useEffect} from 'react';
import { StyleSheet, Text, View, Image, TouchableOpacity, ScrollView} from 'react-native';

const main = 'https://storage.googleapis.com/sparta-image.appspot.com/lecture/main.png'
import data from '../data.json';
import Card from '../components/Card';
import Loading from '../components/Loading';
import { StatusBar } from 'expo-status-bar';
export default function MainPage({navigation,route}) {
  const [state,setState] = useState([])
  const [cateState,setCateState] = useState([])
  const [ready,setReady] = useState(true)

  useEffect(()=>{
    setTimeout(()=>{
        navigation.setOptions({
          title:'메인 페이지'
        })  
        setState(data.tip)
        setCateState(data.tip)
        setReady(false)
    },1000)
 
    
  },[])

  const category = (cate) => {
    if(cate == "전체보기"){
        setCateState(state)
    }else{
        setCateState(state.filter((d)=>{
            return d.category == cate
        }))
    }
}

  let todayWeather = 10 + 17;
  let todayCondition = "흐림"

  return ready 
    ? <Loading/> 
    :  (
        <ScrollView style={styles.container}>
          <StatusBar style="light" />
          <Image style={styles.mainImage} source={{uri:main}}/>
          <View style={styles.cardContainer}>
             {
              cateState.map((content,i)=>{
                return (<Card content={content} key={i} navigation={navigation}/>)
              })
            }
          </View>
        </ScrollView>
       )
}

 

navigation.setOptions({ title:'메인 페이지' })  

 

navigation.setOptions를 사용하여 현재 페이지의 타이틀, 배경색깔등을 변경할 수 있습니다

 

 

반응형

 

<Card navigation={navigation}  />

 

위와 같이 컴포넌트에 navigation을 전달하게되면

해당 컴포넌트 내부에서 navigation을 사용하여 detailPage 화면으로 이동할 수 있습니다.

 

 

Card.js

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

export default function Card({content,navigation}){
    return(
        <TouchableOpacity style={styles.card} onPress={()=>{navigation.navigate('DetailPage',content)}}>
            <Image style={styles.cardImage} source={{uri:content.image}}/>
            <View style={styles.cardText}>
                <Text style={styles.cardTitle} numberOfLines={1}>{content.title}</Text>
                <Text style={styles.cardDesc} numberOfLines={3}>{content.desc}</Text>
                <Text style={styles.cardDate}>{content.date}</Text>
            </View>
        </TouchableOpacity>
    )
}

 

navigation.navigate('DetailPagae', content)

 

인자 값으로 받은 content와, navigation 두개를 활용하여

<TouchableOpacity /> 컴포넌트에서 onPress 속성에 스택네비게이션 함수를 사용하는 모습을 볼 수 있습니다

 

 

그래서 MainPage에서 Card 리스트가 노출되어 클릭을 하는 순간

Card의 이벤트로 DetailPage로 화면이동이 됩니다

 

 

DetailPage.js

import React,{useState,useEffect} from 'react';
import { StyleSheet, Text, View, Image, ScrollView,TouchableOpacity,Alert } from 'react-native';

export default function DetailPage({navigation,route}) {
    const [tip, setTip] = useState({
        "idx":9,
        "category":"재테크",
        "title":"렌탈 서비스 금액 비교해보기",
        "image": "https://storage.googleapis.com/sparta-image.appspot.com/lecture/money1.png",
        "desc":"요즘은 정수기, 공기 청정기, 자동차나 장난감 등 다양한 대여서비스가 활발합니다. 사는 것보다 경제적이라고 생각해 렌탈 서비스를 이용하는 분들이 늘어나고 있는데요. 다만, 이런 렌탈 서비스 이용이 하나둘 늘어나다 보면 그 금액은 겉잡을 수 없이 불어나게 됩니다. 특히, 렌탈 서비스는 빌려주는 물건의 관리비용까지 포함된 것이기에 생각만큼 저렴하지 않습니다. 직접 관리하며 사용할 수 있는 물건이 있는지 살펴보고, 렌탈 서비스 항목에서 제외해보세요. 렌탈 비용과 구매 비용, 관리 비용을 여러모로 비교해보고 고민해보는 것이 좋습니다. ",
        "date":"2020.09.09"
    })
    
    useEffect(()=>{
        console.log(route)
        navigation.setOptions({
            title:route.params.title,
            headerStyle: {
                backgroundColor: '#000',
                shadowColor: "#000",
            },
            headerTintColor: "#fff",
        })
        setTip(route.params)
    },[])

    const popup = () => {
        Alert.alert("팝업!!")
    }
    return ( 
        <ScrollView style={styles.container}>
            <Image style={styles.image} source={{uri:tip.image}}/>
            <View style={styles.textContainer}>
                <Text style={styles.title}>{tip.title}</Text>
                <Text style={styles.desc}>{tip.desc}</Text>
                <TouchableOpacity style={styles.button} onPress={()=>popup()}><Text style={styles.buttonText}>팁 찜하기</Text></TouchableOpacity>
            </View>
        </ScrollView>
    
    )
}

 

Card 컴포넌트에서 두번째 인자값으로 content를 전달했었죠?

 

navigation.navigator 함수로 전달 할 경우

Stack.Screen으로 component를 연결해야지만 router로 받을수 있습니다

 

router.params 안에 객체의 값이 들어 있으니 참고하세요!

 

 

 

지금까지 스택네비게이션을 알아보았습니다.

복잡하지만 차근 차근 구조를 익히다보면 쉽게 하실수 있을거예요

 

마지막으로 간략히 설명하자면,

 

처음 스택네비게이션을 설치 후

파일을 만든다음 Stack.Navigator의 부모태그와 Stack.Screen의 자식태그로 지정하여

코드를 작성해주고 원하는 페이지를 속성으로 묶어 주기만하면 끝이라는 점!

 

그리고

부모태그 자식태그의 파일을 import 해서 사용하기만 하면

된다는 점을 인지하여 주시길바랍니다

 

 

이렇게 오늘도 저도 복습하며 블로그를 이어나가네요

요즘 다시 블로그를 살려볼려고 힘을 내고 있습니다

 

모두들 대모험은 아직 끝나지 않았습니다

화이팅 하시고 

 

다음 포스팅에서 뵐게요~

 

 

이전 포스팅은 밑에서~

2022.06.30 - [모바일/React Native] - [React Native X Expo] View, ScrollView, Text, Button, TouchableOpacity, Image 엘리먼트 & 태그 활용 리액트 네이티브

 

[React Native X Expo] View, ScrollView, Text, Button, TouchableOpacity, Image 엘리먼트 & 태그 활용 리액트 네이티

View, ScrollView, Text, Button, Image 엘리먼트 & 태그 활용 엘리먼트 활용 화면의 영역(레이아웃)을 잡아주는 엘리먼트이다. App.js 상에서 View는 화면 전체 영역을 가진다. 아래와 같이 화면을 분할.

tantangerine.tistory.com

 

728x90
반응형
728x90
반응형

View, ScrollView, Text, Button, Image 엘리먼트 & 태그 활용 

<View> 엘리먼트 활용

  • 화면의 영역(레이아웃)을 잡아주는 엘리먼트이다.
  • App.js 상에서 View는 화면 전체 영역을 가진다.
  • 아래와 같이 화면을 분할할 수 있다.
import { StatusBar } from 'expo-status-bar';
import React from 'react';
import { StyleSheet, Text, View } from 'react-native';

export default function App() {
  return (
    <View style={styles.container}>
      <View style={styles.subContainerOne}></View>
      <View style={styles.subContainerTwo}></View>
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#fff',
  },
  subContainerOne: {
    flex:1,
    backgroundColor:"yellow"
  },
  subContainerTwo: {
    flex:1,
    backgroundColor:"green"
  }
});
  • 각 태그들에는 style이라는 속성을 가지고 있다
  • 속성은 하단에 스타일 코드 객체의 키값을 할당하여 엘리먼트에 스타일을 부여한다

 

View호 화면을 분할하고 영역을 나누려면

스타일 문법(StyleSheet)과 같이 사용해야 한다

 

스타일 문법(StyleSheet)은 다음 포스팅에서 확인하고

View는 화면의 영역을 잡는 엘리먼트라는 것만 알아두자

 

 

아래의 이미지는 위의 코드로 표현한 앱 화면이다 

상위 View엘리먼트 안에 하위 2개의 View 엘리먼트로 인해 2개의 영역이 표현된다.

코드로 표현한 앱화면이다

 


 

<ScrollView> 엘리먼트 활용

  • 앱 화면에 노출되는 영역보다 엘리먼트가 벗어나면 ScrollView 엘리먼트를 사용하면 스크롤이 가능하다
import React from 'react';
import { StyleSheet, Text, View, ScrollView } from 'react-native';

export default function App() {
  return (
    <ScrollView style={styles.container}>
      <View style={styles.textContainer}>
        <Text style={styles.textStyle}>영역을 충분히 갖는 텍스트 입니다!</Text>
      </View>
      <View style={styles.textContainer}>
        <Text style={styles.textStyle}>영역을 충분히 갖는 텍스트 입니다!</Text>
      </View>
      <View style={styles.textContainer}>
        <Text style={styles.textStyle}>영역을 충분히 갖는 텍스트 입니다!</Text>
      </View>
      <View style={styles.textContainer}>
        <Text style={styles.textStyle}>영역을 충분히 갖는 텍스트 입니다!</Text>
      </View>
      <View style={styles.textContainer}>
        <Text style={styles.textStyle}>영역을 충분히 갖는 텍스트 입니다!</Text>
      </View>
      <View style={styles.textContainer}>
        <Text style={styles.textStyle}>영역을 충분히 갖는 텍스트 입니다!</Text>
      </View>
      <View style={styles.textContainer}>
        <Text style={styles.textStyle}>영역을 충분히 갖는 텍스트 입니다!</Text>
      </View>
    </ScrollView>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#fff',
  },
  textContainer: {
    height:100,
    borderColor:'#000',
    borderWidth:1,
    borderRadius:10,
    margin:10,
  },
  textStyle: {
    textAlign:"center"
  }
});

 

상위 엘리먼트를  View로 구현했다면 마지막 부분이 짤려서 보이질 않는다.

ScrollView를 사용하면 스크롤이 가능해지면서 마지막부분도 보이게된다.

 

위의 코드로 표현된 앱 화면

 


반응형

<Text> 엘리먼트 활용

  • 앱에 글을 표현하려면 꼭 사용해야 할 엘리먼트이다.
  • 방금 전 위에서 배운 ScrollView 엘리먼트 안에 문자를 작성하면 오류가 발생한다.
import React from 'react';
import { StyleSheet, Text, View } from 'react-native';

export default function App() {
  return (
    <View style={styles.container}>
      <Text>문자는 Text 태그 사이에 작성!!</Text>
      <Text>문자는 Text 태그 사이에 작성!!</Text>
      <Text>문자는 Text 태그 사이에 작성!!</Text>
      <Text>문자는 Text 태그 사이에 작성!!</Text>
      <Text>문자는 Text 태그 사이에 작성!!</Text>
      <Text>문자는 Text 태그 사이에 작성!!</Text>
      <Text>문자는 Text 태그 사이에 작성!!</Text>
      <Text>문자는 Text 태그 사이에 작성!!</Text>
      <Text>문자는 Text 태그 사이에 작성!!</Text>
      <Text>문자는 Text 태그 사이에 작성!!</Text>
      <Text>문자는 Text 태그 사이에 작성!!</Text>
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#fff',
    alignItems: 'center',
    justifyContent: 'center',
  },
});

 


 

<Button> 엘리먼트 활용

  • Button 태그를 이용해서 손쉽게 버튼을 만들 수 있다
  • Button 태그에는 title, color, onPress 등의 속성을 가지고 있는데, 속성을 잘 활용하면 여러기능을 구현할 수 있다.
import React from 'react';
import { StyleSheet, Text, View, Button, Alert } from 'react-native';

export default function App() {
  const customAlert = () => {
    Alert.alert("JSX 밖에서 함수 구현 가능!")
  }
  return (
    <View style={styles.container}>
      <View style={styles.textContainer}>
        <Text style={styles.textStyle}>아래 버튼을 눌러주세요</Text>
        <Button 
          style={styles.buttonStyle} 
          title="버튼입니다 "
          color="#f194ff" 
          onPress={customAlert}
        />
        <Button 
            style={styles.buttonStyle} 
            title="버튼입니다 "
            color="#FF0000" 
            onPress={() => {customAlert()}}
          />
          </View>
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#fff',
  },
  textContainer: {
    height:100,
    margin:10,
  },
  textStyle: {
    textAlign:"center"
  },
});

 

위의 코드는 Button 태그에 onPress 속성을 부여하여 앱화면 버튼영역 터치시 얼럿창을 노출하는 기능을 구현한 것이다

함수는 ES6문법인 화살표 함수를 사용해도 된다.

하지만 Button 태그는 자신의 영역을 갖기때문에 스타일을 부여하기가 어려움이 있다.

아래의 코드 처럼 ScrollView에서 카드 형식으로 만든 앱 화면이면 Button 태그를 사용하기 어렵다 그러므로 <TouchableOpacity> 태그를 활용하면 화면에 영향을 주지않고 쉽게 구현할 수 있다.

 


 

<TouchableOpacity> 태그를 활용해서 Button 태그 대체하기 

  • <ScrollView> 상위 태그로 하위태그는 View를 사용하지만 그것을 TouchableOpacity태그로 대체하면 임의의 영역과 디자인에 버튼 기능을 구현하고 싶을경우 주로 사용한다
import React from 'react';
import { StyleSheet, Text, View, ScrollView, TouchableOpacity, Alert } from 'react-native';

export default function App() {
  const customAlert = () => {
    Alert.alert("TouchableOpacity에도 onPress 속성이 있습니다")
  }
  return (
    <ScrollView style={styles.container}>
      <TouchableOpacity style={styles.textContainer} onPress={customAlert}>
        <Text style={styles.textStyle}>영역을 충분히 갖는 텍스트 입니다!</Text>
      </TouchableOpacity>
      <TouchableOpacity style={styles.textContainer} onPress={customAlert}>
        <Text style={styles.textStyle}>영역을 충분히 갖는 텍스트 입니다!</Text>
      </TouchableOpacity>
      <TouchableOpacity style={styles.textContainer} onPress={customAlert}>
        <Text style={styles.textStyle}>영역을 충분히 갖는 텍스트 입니다!</Text>
      </TouchableOpacity>
      <TouchableOpacity style={styles.textContainer} onPress={customAlert}>
        <Text style={styles.textStyle}>영역을 충분히 갖는 텍스트 입니다!</Text>
      </TouchableOpacity>
      <TouchableOpacity style={styles.textContainer} onPress={customAlert}>
        <Text style={styles.textStyle}>영역을 충분히 갖는 텍스트 입니다!</Text>
      </TouchableOpacity>
      <TouchableOpacity style={styles.textContainer} onPress={customAlert}>
        <Text style={styles.textStyle}>영역을 충분히 갖는 텍스트 입니다!</Text>
      </TouchableOpacity>
      <TouchableOpacity style={styles.textContainer} onPress={customAlert}>
        <Text style={styles.textStyle}>영역을 충분히 갖는 텍스트 입니다!</Text>
      </TouchableOpacity>
    </ScrollView>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#fff',
  },
  textContainer: {
    height:100,
    borderColor:'#000',
    borderWidth:1,
    borderRadius:10,
    margin:10,
  },
  textStyle: {
    textAlign:"center"
  }
});

 

 

위와 같이 영역에서 버튼처럼 기능구현이 가능하다

 


 

<Image> 태그 활용해서 앱화면에 이미지를 노출하자

  • 내부 폴더 안에있는 이미지를 사용하는 방법이 있다
  • 여러 속성을 사용해서 이미지를 삽입한다
  • source, resizeMode, style등 여러 속성을 활용할 수 있다.
import React from 'react';
import { StyleSheet, Text, View, Image } from 'react-native';
import favicon from "./assets/favicon.png"

export default function App() {
  return (
    <View style={styles.container}>
      <Image 
        source={favicon}
        resizeMode={"repeat"}
        style={styles.imageStyle}
      />
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#fff',
    justifyContent:"center",
    alignContent:"center"
  },
  imageStyle: {
    width:"100%",
    height:"100%",
    alignItems:"center",
    justifyContent:"center"
  }
});

 

 

resizeMode를 repeat로 부여했다

 

 

  • 외부 이미지 링크를 사용하는 방식도 있다.
  • 위와 다르게 resizeMode에 repeat을 cover로 변경해서 사용하였다 결과를 아래에서 확인해보자.
import React from 'react';
import { StyleSheet, Text, View, Image } from 'react-native';
import favicon from "./assets/favicon.png"

export default function App() {
  return (
    <View style={styles.container}>
      <Image 
        source={{uri:'https://images.unsplash.com/photo-1424819827928-55f0c8497861?fit=crop&w=600&h=600%27'}}
        resizeMode={"cover"}
        style={styles.imageStyle}
      />
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#fff',
    justifyContent:"center",
    alignContent:"center"
  },
  imageStyle: {
    width:"100%",
    height:"100%",
    alignItems:"center",
    justifyContent:"center"
  }
});

 

resizeMode를 cover로 부여했다

 

 

앱 화면을 구현하기위해 기초적인 태그들을 정리해보았다

앞으로 React Native를 활용해서 Expo와 같이 구현한다

 Expo에 대한 장점과 단점은 분명하며 어떤 앱을 구현할때 Expo가 유리할지도 생각해보아야겠다

앞으로 어떤앱이 탄생할지 계속해서 만들어보자

 

728x90
반응형

+ Recent posts

Powered by Tistory, Designed by wallel