리액트 네이티브 튜토리얼
[#1 리액트 네이티브 맛보기]
[#2 Component와 메인화면 분할]
[#3 레이아웃 구성하기]
[#4 레이아웃 구현 마무리하기]
[#5 state]
[#6 설정 Modal 만들기]
[#7 설정 Modal 기능 추가하기]
[#8(구현 끝) 채팅기능 구현하기]

 

이번시간에는 설정 버튼을 눌렀을 때, 디데이 제목과 날짜를 설정할 수 있는 모달창을 만들어 보겠습니다.

먼저 Setting컴포넌트를 만들기 위해 새로운 js파일을 생성할 거에요.

App.js가 있는 프로젝트 폴더에 Setting.js를 생성해주세요.

//Setting.js
import React from 'react';
import {View, StyleSheet, Text, TextInput, TouchableOpacity} from 'react-native';

export default class Setting extends React.Component {

  render() {
    return (
      <View  style={styles.container}>
		<Text>설정창</Text>
      </View>
    );
  }
}

const styles = StyleSheet.create({

});

 

기본적인 뼈대 코드를 입력해주세요.

설정창이 어떻게 렌더링 되는지 확인하기 위해서 "설정창"이라고 표시되는 Text컴포넌트를 하나 작성했습니다.

//App.js
import React from 'react';
import { StyleSheet, Text, View, Image, TextInput,TouchableOpacity, ScrollView, ImageBackground} from 'react-native';
import Setting from './Setting.js';

생성한 Setting컴포넌트를 사용하기 위해서 App.js의 최상단에 import하는 부분에 Setting.js를 import해주세요.

//App.js

 render() {
    return (
      <View style={styles.container}>
        <ImageBackground
          style={{width: '100%', height: '100%'}}
          source={require('./images/background.png')}>

        <View style={styles.settingView}>

          <TouchableOpacity onPress={()=>this.toggleSettingModal()}>
            <Image source={require('./icon/setting.png')}/>
          </TouchableOpacity>
        </View>
        <View style={styles.ddayView}>
          <Text style={styles.titleText}>
            {this.state.ddayTitle}까지
          </Text>
          <Text style={styles.ddayText}>
            D-123
          </Text>
          <Text style={styles.dateText}>
            2020년 11월 32일
          </Text>
        </View>
        <View style={styles.chatView}>
          <ScrollView style={styles.chatScrollView}>
          </ScrollView>
          <View style={styles.chatControl}>
            <TextInput style={styles.chatInput}/>
            <TouchableOpacity style={styles.sendButton}>
              <Text>
                전송
              </Text>
            </TouchableOpacity>
          </View>
        </View>
            <Setting/> //여기에 추가해주세요.
        </ImageBackground>
      </View>
    );
  }
}

Setting컴포넌트를 ImageBackground내부의 최하단에 작성해주세요.

react native의 경우 아래에 선언된 컴포넌트가 이전에 선언된 컴포넌트를 덮습니다.

modal의 경우 스크린에서 가장 상위에(모든 컴포넌트들을 덮으면서) 렌더링되어야 하기 때문에, 가장 하단부에 선언합니다.

이처럼 설정창 이라는 Text가 렌더링되면서 이전에 작성했던 Setting.js가 렌더링된다는 것을 알 수 있습니다.

만들고자하는 세팅 모달을 미리 보겠습니다.

가장 먼저 모달 외부영역은 약간 어둡게 처리해서 눌렀을 때, 모달이 사라지게 만들거에요.

그리고 제목과 날짜를 설정할 수 있는 컴포넌트와 완료버튼으로 이루어져 있습니다.

//Setting.js

  render() {
    return (
      <View  style={styles.container}>
        <TouchableOpacity style={styles.background}/>
        <View style={styles.modal}>
          <Text style={styles.titleText}>설정</Text>
          <TextInput/>
          <TouchableOpacity>
            <Text style={styles.doneText}>
              완료
            </Text>
          </TouchableOpacity>
        </View>
      </View>
    );
  }

 

Setting.js로 돌아와서 구성요소들을 작성해줍니다.

날짜 선택은 외부 라이브러리를 사용할 예정이라 나중에 추가할게요.

상단의 TouchableOpacity는 외부영역을 터치했을 때 모달을 닫아주기 위해 사용됩니다.

//Setting.js


const styles = StyleSheet.create({
  container: {
    position: 'absolute',
    height: '100%',
    width: '100%',
    backgroundColor: 'transparent'
  },
  background: {
    position: 'absolute',
    height: '100%',
    width: '100%',
    backgroundColor: 'rgba(0,0,0,0.5)'
  },
  ddayInput: {
    backgroundColor: 'white',
    marginBottom: 20,
    width: '75%',
    height: 40,
    borderBottomWidth: 1,
    borderBottomColor: '#a5a5a5'
  },
  modal: {
    marginHorizontal: 20,
    borderRadius: 10,
    alignItems: 'center',
    marginTop: '50%',
    backgroundColor: 'white',
  },
  doneText: {
    color: 'rgb(1,123,255)',
    fontSize: 15,
    margin: 10
  },
  titleText: {
    fontSize: 18,
    margin: 10
  }
});

각 컴포넌트를 위해 style을 작성합니다.

container와 background는 position을 absolute로 지정한뒤, height와 width를 100%로 조정해 화면에 가득차게 설정합니다.

background의 backgroundColor설정에 사용했던 rgba는 r, g, b, a값을 차례로 설정해줍니다.

이때 마지막 a값은 투명도를 나타내므로 0.5값을 줘서 뒤의 배경이 비치게 만들어 살짝 어두워 지는 듯한 효과를 내줍니다.

위의 스타일은 자기가 원하는 스타일대로 조정해보세요.

뒷 배경이 살짝 어두워지면서 모달창이 뜨게됩니다.

이제 디데이 제목과 날짜를 state로 지정해보겠습니다.

//Setting.js
import React from 'react';
import {View, StyleSheet, Text, TextInput, TouchableOpacity} from 'react-native';

export default class Setting extends React.Component {

  constructor(props) {
    super(props);
    this.state = {
      title: '',
      date: new Date(),
    }
  }
  
  render() {
    return (
      <View  style={styles.container}>
      ... 생략

constructor를 작성하고 임시로 title과 date를 초기화 해줍니다.

이제 react-native-date-picker라는 외부 라이브러리를 이용해서 날짜선택하는 기능을 추가해보겠습니다.

github.com/henninghall/react-native-date-picker

 

henninghall/react-native-date-picker

React Native Date Picker is an inline datepicker for Android and iOS. It includes date, time and datetime picker modes. The datepicker is customizable and is supporting different languages. It'...

github.com

위의 사이트는 해당 컴포넌트의 github페이지 입니다. 설치방법부터 사용법을 확인할때 참고하시면 됩니다.

npm install react-native-date-picker --save로 설치해줍니다. 해당 명령어는 프로젝트 폴더에서 입력하시면 됩니다.

설치하기 전, 실행중인 metro server는 꺼주시는 게 좋습니다.

설치후 에러가 발생하거나 하는 경우는 reactnative를 재실행 해주세요.

//Setting.js
import React from 'react';
import {View, StyleSheet, Text, TextInput, TouchableOpacity} from 'react-native';
import DatePicker from 'react-native-date-picker'

설치가 완료되었으면, Setting.js에 상단에 DatePicker를 import해주세요.

 //Setting.js
 
 render() {
    return (
      <View  style={styles.container}>
        <TouchableOpacity style={styles.background}/>
        <View style={styles.modal}>
          <Text style={styles.titleText}>설정</Text>
          <TextInput/>
          <DatePicker
            date={this.state.date}
            mode="date"/>
          <TouchableOpacity>
            <Text style={styles.doneText}>
              완료
            </Text>
          </TouchableOpacity>
        </View>
      </View>
    );
  }

DatePicker github을 참고해보면, date에는 default로 선택될 날짜를 설정합니다.

현재는 this.state.date를 주었고, date를 state초기화 할때 new Date()로 했기 때문에 현재 날짜가 default로 뜨게 됩니다.

그리고 디데이날짜(시:분:초 가 아닌 날짜만)를 선택할 것이므로 mode="date"로 날짜모드로 동작하게 설정합니다.

공식 문서를 참고해서 여러가지 옵션을 설정해보세요.

현재까지 완성된 모습입니다.

//Setting.js

  render() {
    return (
      <View  style={styles.container}>
        <TouchableOpacity style={styles.background}/>
        <View style={styles.modal}>
          <Text style={styles.titleText}>설정</Text>
          <TextInput
            style={styles.ddayInput}
            value={this.state.title}
            onChangeText={(changedText)=>{this.setState({title: changedText})}}
            placeholder={"디데이 제목을 입력해주세요."}/>
          <DatePicker
            date={this.state.date}
            mode="date"/>
          <TouchableOpacity>
            <Text style={styles.doneText}>
              완료
            </Text>
          </TouchableOpacity>
        </View>
      </View>
    );
  }
}

Textinput을 조금 다듬고 레이아웃은 마무리하겠습니다.

value에 설정한 값이 TextInput에 입력값으로 들어갑니다.

따라서 아까 설정했던 this.state.title로 지정해줍니다.

또한 onChangeText는 TextInput에 입력이 되어서 텍스트가 변경되는 경우 실행되는 함수를 설정하는 옵션 입니다.

()=>{}형식의 함수가 익숙하지 않다면, developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Functions/%EC%95%A0%EB%A1%9C%EC%9A%B0_%ED%8E%91%EC%85%98 를 보고오시는 것을 추천드립니다.

 

화살표 함수

화살표 함수 표현(arrow function expression)은 function 표현에 비해 구문이 짧고  자신의 this, arguments, super 또는 new.target을 바인딩 하지 않습니다. 화살표 함수는 항상 익명입니다. 이  함수 표현은 메

developer.mozilla.org

(changedText)=>{this.setState({title: changedText})}는 인자를 changedText로 받아서(주어지는 인자는 change된 text입니다.) setState를 통해서 state의 값을 바꿔줍니다.

setState는 인자로 object를 전달받는데, {title: changedText}는 title이라는 state에 changedText(아까 인자로 받았던 것)을 저장하게됩니다.

state의 경우 this.state.title = changedText처럼 사용해도 state값이 변경되기는 하지만, react native는 저런 방식으로 state를 수정하는 경우 즉시 반영되지 않습니다.

따라서 setState를 이용해서 변경해줘야 state가 즉시 바뀌기 때문에, state를 조작할때는 setState를 이용합니다.

placeholder의 경우, TextInput에 아무 입력값이 없을때 표시되는 텍스트입니다.

여기까지 진행된 모습입니다.

다음글에서는 완료버튼, 배경클릭시 모달 닫기, 날짜, 제목설정 등 기능을 구현해보겠습니다.

 

복사했습니다!