elevne's Study Note

React Native (3-2: RN 날씨앱 만들어보기) 본문

Frontend/React Native

React Native (3-2: RN 날씨앱 만들어보기)

elevne 2023. 2. 18. 18:05

저번 시간에 작성했던 코드에서 거의 변경사항이 없다. 우선 가장 중심이 되는 Weather.js 의 최종 코드는 아래와 같이 구성되었다.

 

 

 

import { useCallback, useEffect, useState } from "react";
import { StyleSheet, Text, View, TextInput, Image, ImageBackground } from "react-native";
import Forecast from "./Forecast";
import open_weather_map from "./open_weather_map";

const Weather = () => {
    const [info, setInfo] = useState({
        zip: "",
        forecast: null
    });
    const [content, setContent] = useState(null)
    let handleChange = event => {
        let txt = event.nativeEvent.text;

        setInfo({zip:txt, forecast: {
            main: "SNOW", description: "SEOUL SNOW", temp: 2
        }})
        console.log(info)
        func()
        console.log(content)

        // open_weather_map.fetchForecast(txt).then(forecast => {
        //     console.log(forecast);
        //     setInfo({zip:txt, forecast:forecast})
        // })

    }
    let func = useCallback(() => {
        if (info.forecast != null) {
            setContent(
                <Forecast 
                    main = {info.forecast.main}
                    description = {info.forecast.description}
                    temp = {info.forecast.temp}
                />
            )
        }
    }, [info])
    useEffect(() => {
        func()
    }, [info])
    return (
        <View style={styles.container}>
            <ImageBackground
                source={require("./bg_img.jpg")}
                resizeMode="cover"
                style={styles.backdrop}
            >
                <View style={styles.overlay}>
                    <View style={styles.row}>
                        <Text style={styles.mainText}>
                            Current Weather For
                        </Text>
                        <View style={styles.zipContainer}>
                            <TextInput style={[styles.zipCode, styles.mainText]}
                                    onSubmitEditing={event => handleChange(event)}
                                    underlineColorAndroid="transparent" />
                        </View>
                    </View>
                    {content}
                </View>
            </ImageBackground>


{/*            <Text style={styles.welcome}>
                Your Input: {info.zip}
            </Text>
            {content}
            <TextInput style={styles.input} onSubmitEditing={event => handleChange(event)}/> */}


        </View>
    )
}

const baesFontSize = 16;

const styles = StyleSheet.create({
    container: {
        flex: 1,
        alignItems: "center",
        paddingTop: 30
    },
    backdrop: {
        flex: 1,
        flexDirection: "column"
    },
    overlay: {
        paddingTop: 5,
        backgroundColor: "#000000",
        opacity: 0.5,
        flexDirection: "column",
        alignItems: "center"
    },
    row: {
        flexDirection: "row",
        flexWrap: "nowrap",
        alignItems: "flex-start",
        padding: 30
    },
    zipContainer: {
        height: baesFontSize + 10,
        borderBottomColor: "#DDDDDD",
        borderBottomWidth: 1,
        marginLeft: 5,
        marginTop: 3
    },
    zipCode: {
        flex: 1,
        flexBasis: 1,
        width: 50,
        height: baesFontSize
    },
    mainText: {
        fontSize: baesFontSize,
        color: "#FFFFFF"
    }
})

export default Weather;

 

 

 

OpenWeatherMap 에서 날씨 정보를 fetch 해오는 부분은 계속 invalid API key 문제가 발생하여 주석처리를 해두었다. 그 외로는, 스타일들을 많이 추가, 변경하였고 ImageBackground 컴포넌트를 사용하여 바탕화면에 이미지를 넣을 수 있도록 하였다. 

 

 

사용한 Style 들 중 flex에 대해서 알아보았다. 위에서 사용된 flex 속성은 flexGrow, flexShrink, flexBasis 를 한 번에 나타내는 것이라고 한다. flexBasis 는 사용가능한 공간이 분배되기 전에 flex item 에 초기 크기를 설정해준다. flex item 의 초기 크기를 지정하기는 하지만, flexGrow 와 flexShrink 속성에 의해 재정의될 수 있다. flexGrow 는 사용가능한 공간이 추가되었을 때 동일한 flex container 의 다른 flex item 과 비교하여 flex item 이 얼마나 증가해야하는지를 지정한다. Unitless 한 값이며, 기본값은 0 으로 설정되어 있어 flex item 이 커지지않는다. 즉, flexBasis 를 제외한 나머지 여백을 그 값의 비율대로 나눠갖게 되는 것이다. flexShrink 는 flexGrow 와 반대로 줄어드는 속성을 의미하는 것으로, 이 또한 디폴트 값은 0 으로 설정되어 있다.

 

 

flex: 1 을 지정해주게 되는 것은 flexGrow:1, flexShrink:1, flexBasis: 0% 로 설정하는 것과 같다고 한다. 부모인 flex container 의 너비가 변하게될 때에 그 자식도 동일한 비율로 변하게 한다. 또, flexDirection 을 따로 지정해줄 수 있는데 이는 내부의 아이템들이 만들어지는 방향을 지정해주는 속성이다. column 으로 그 값을 지정하면 수직으로 아이템들이 추가되고, row 로 지정하면 수평적으로 아이템들이 추가되는 것이다. 

 

 

 

최종적인 화면은 아래와 같이 구성되었다.

 

 

 

result

 

 

 

 

 

 

Reference:

https://velog.io/@mooongs/flex1%EC%9D%98-%EC%9D%98%EB%AF%B8

https://ipex.tistory.com/entry/CSS3-flex-Box-flexdirection-%EC%83%9D%EC%84%B1-%EB%B0%A9%ED%96%A5

빠른 모바일 앱 개발을 위한 React Native