Engineering

Tutorial: React Native 메시지 앱 제작하기

Avatar
James Kim Software Engineer - Web Applications
Share

Get Started!

1,000 MAU and 25 connections free forever

Start Now

안내드립니다: 최근 (2017년 11월 10일 기준) 센드버드 샘플 코드와 함께 본 튜터리얼을 최신버전으로 업데이트 하였습니다. 가장 최신의 ‘React Native 채팅 튜터리얼’ 시리즈 블로그를 확인해보세요.

다음의 Tutorial은 구버전에 해당하는 SDK 2.0을 바탕으로 제작되었습니다.  원활한 작업 및 지원(support)을 위해 반드시 새로운 SDK 3.0 버젼을 통해 만들어진 Sample Code를 따라 Tutorial을 진행하시길 권장합니다. – [Click to the sample for SDK 3.0]


안녕하세요. 센드버드의 Software Engineer 김범준입니다.

React와 React Native의 관심이 뜨겁습니다. 그 중 React Native에서 SendBird의 JavaScript SDK를 이용하여 쉽고 빠르게 채팅 앱을 만드는 과정을 소개해 드리고자 합니다.

1. React Native 장점 살펴보기

대다수의 모바일 앱은 네이티브 앱 형식으로 제작이 되고 있습니다. 하이브리드 앱으로 제작을 하게 되는 경우 ‘웹뷰(Webview)’를 이용하게 되는데, 이렇게 할 경우 네이티브 앱에서 지원하는 속성을 이용하기 힘들다는 단점이 있습니다. 하지만, React Native를 이용하면 네이티브 속성을 그대로 이용할 수 있습니다.

 http://facebook.github.io/react-native/docs/datepickerios.html#content

또한 웹뷰를 이용하여 제작할 경우 네이티브 앱에 비해 느리다는 단점이 있습니다. React Native는 자바스크립트 코드와 네이티브 코드를 별도의 스레드로 분리하여 둘 사이의 통신을 비동기식으로 만들어 느려지는 현상이 없습니다. 따라서 기존의 하이브리드 앱보다 뛰어난 성능을 보여주게 됩니다.

또한, React Native는 기존의 네이티브 앱 제작 능력이 없는 개발자라 하더라도, 자바스크립트를 사용할 수 있다면, 쉽고 빠르게 학습하여 즉시 활용할 수 있다는 것이 큰 장점입니다.

React Native는 이미 iOS버전의 페이스북 그룹과 Facebook Ads Manager(AndroidiOS)등의 페이북 앱에서 사용되고 있습니다.

 https://itunes.apple.com/us/app/facebook-groups/id931735837

2. React Native Tutorial with SendBird JavaScript SDK

본문은 다음과 같이 구성되어 있습니다.

  1. React Native 환경 설정
  2. Login 만들기 – 1) 화면 구성하기, 2) 입력창 만들기, 3) Debug 하기 4) SendBird에 Login하기
  3. 채널 목록 만들기 – 1) 화면 구성하기, 2) 채널 목록 가져오기, 3) 채널 입장하기
  4. 채팅 화면 – 1) 화면 구성하기, 2) 뒤로가기 버튼과 입력창 구성, 3) 채팅 주고 받기

 https://sendbird.com/

1) React Native 환경설정

튜토리얼에 앞서 채팅을 쉽게 구현하기 위해 필요한 센드버드의 JavaScript SDK는 현재 Bower와 npm을 이용하여 편하게 사용할 수 있으며, 필요한 경우 Github 저장소에서 다운로드 하실 수 있습니다. 이 JavaScript SDK를 이용하여 React Native에서 iOS용 앱을 제작하여 채팅이 가능하도록 하는 과정을 보여드리도록 하겠습니다.

React Native 버전은 0.20.0을 사용했으며, SendBird JavaScript SDK는 2.1.6버전을 사용했습니다. 에디터 툴로는 Atom을 사용했습니다. (Atom 에디터는 굉장히 훌륭한 에디터이지만, 개인적으로 사용하고 있는 다른 에디터를 사용하셔도 무방합니다.)
이 튜토리얼은 OS X 기준으로 제작되었으며 사용된 React Native 기능들은 다음과 같습니다.

최종 완성본은 이곳에서 다운로드 받으실 수 있습니다.

React Native를 개발하기 위한 환경설정을 하도록 하겠습니다. React Native의 공식 홈페이지에 있는 Getting Started에 굉장히 친절하게 나와 있으니 참고하시면 많은 도움이 되실거라 생각합니다.

Node.js 4.0 혹은 그 이상 버전의 설치가 필요합니다.
파일변경을 감시하기 위해 watchman설치를 권장합니다.
마지막으로 React Native를 설치하도록 합니다.

npm install -g react-native-cli

이렇게 하면 우리는 React Native개발을 위한 모든 준비가 완료된 상태입니다.

프로젝트를 생성해 보도록 하겠습니다.

react-native init SendBirdSample

생성이 완료후 해당 프로젝트 폴더를 사용하는 에디터를 이용하여 열어보면 다음과 같은 구조로 되어 있는 것을 확인 하실 수 있습니다.

센드버드의 JavaScript SDK를 다운로드 받아서 프로젝트 폴더에 복사 후 사용하는 방법도 가능하지만, 이번에는 npm을 이용하여 설치를 진행하도록 하겠습니다.

cd SendBirdSample
npm install sendbird --save

설치가 완료되면 package.json파일을 통해서 설치된 package를 확인 할 수 있습니다.

2) Login 만들기

2-1) 화면 구성하기

Xcode를 이용하여 빌드를 해도 되지만, 이곳에서는 명령어를 통해 React Native를 실행해 보도록 하겠습니다.

npm start
react-native run-ios

위의 두 명령을 실행하면 다음과 같은 화면이 보입니다.

이곳에서는 화면의 전환을 위해 Navigator라는 컴퍼넌트(Component)를 이용하도록 하겠습니다.

우선, 프로젝트 폴더 안에 src라는 폴더를 생성하고 그곳에 main.js 파일을 생성합니다. 그 다음, src폴더 안에 components라는 폴더를 생성하고 그곳에 login.js 파일을 생성합니다.

index.ios.js 파일을 다음과 같이 수정하겠습니다.

var React = require('react-native');
var {
  AppRegistry
} = React;

var Main = require(‘./src/main’)

AppRegistry.registerComponent(‘SendBirdSample’, () => Main);

src/main.js 파일을 다음과 같이 수정하겠습니다.

var React = require('react-native')
var {
  Navigator,
  StyleSheet
} = React;

var Login = require(‘./components/login’);

var ROUTES = {
login: Login
};

module.exports = React.createClass({
renderScene: function(route, navigator) {
var Component = ROUTES[route.name];
return <Component route={route} navigator={navigator} />;
},
render: function() {
return (
<Navigator
style={ styles.container }
initialRoute={ {name: ‘login’} }
renderScene={this.renderScene}
configureScene={ () => { return Navigator.SceneConfigs.FloatFromRight; } }
/>
);
}
});

var styles = StyleSheet.create({
container: {
flex: 1
}
});

src/components/login.js 파일을 다음과 같이 수정하겠습니다.

var React = require('react-native');
var {
  View,
  Text,
  StyleSheet
} = React;

module.exports = React.createClass({
render: function() {
return (
<View style={styles.container}>
<Text style={{color: ‘white’}}>SendBird JavaScript SDK!!!</Text>
</View>
);
}
});

var styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: ‘center’,
alignItems: ‘stretch’,
backgroundColor: ‘#6E5BAA’
}
});

시뮬레이터를 새로고침(command + R)을 하면 다음과 같은 화면을 볼 수 있습니다.

이곳에서는 ViewTextNavigator, 컴퍼넌트와 StyleSheet API가 사용되었습니다. 공식 문서를 참고하면 더욱 자세한 내용을 확인하실 수 있습니다.

2-2) 입력창 만들기

이제는 사용자의 nickname을 입력받는 곳과 Login버튼을 구현하도록 하겠습니다.

src/conponents/login.js 파일을 다음과 같이 수정하도록 하겠습니다.

var React = require('react-native');
var {
  View,
  Text,
  TextInput,
  TouchableHighlight,
  StyleSheet
} = React;

module.exports = React.createClass({
getInitialState: function() {
return {
username: ”
};
},
render: function() {
return (
<View style={styles.container}>
<View style={styles.loginContainer}>
<TextInput
style={styles.input}
value={this.state.username}
onChangeText={(text) => this.setState({username: text})}
placeholder={‘Enter User Nickname’}
maxLength={12}
multiline={false}
/>

<TouchableHighlight
style={styles.button}
underlayColor={‘#328FE6’}
onPress={this.onPress}
>
<Text style={styles.label}>LOGIN</Text>
</TouchableHighlight>
</View>
</View>
);
},
onPress: function() {
console.log(this.state.username);
}
});

var styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: ‘center’,
alignItems: ‘stretch’,
backgroundColor: ‘#6E5BAA’
},
loginContainer: {
flex: 1,
justifyContent: ‘center’,
alignItems: ‘center’,
},
input: {
width: 250,
color: ‘#555555’,
padding: 10,
height: 50,
borderColor: ‘#32C5E6’,
borderWidth: 1,
borderRadius: 4,
alignSelf: ‘center’,
backgroundColor: ‘#ffffff’
},
button: {
justifyContent: ‘center’,
alignItems: ‘center’,
borderWidth: 1,
borderRadius: 5,
borderColor: ‘#328FE6’,
padding: 10,
marginTop: 10,
backgroundColor: ‘#32c5e6’
},
label: {
width: 230,
flex: 1,
alignSelf: ‘center’,
textAlign: ‘center’,
fontSize: 20,
fontWeight: ‘600’,
color: ‘#ffffff’
}
});

이제 nickname을 입력할 수 있는 입력창과 Login버튼을 확인 할 수 있습니다.

이곳에서는 TextInput과 TouchableHighlight 컴퍼넌트가 추가적으로 사용되었습니다.

2-3) Debug 하기

onPress 함수에 코딩되어 있는 console.log()를 확인하기 위해서는 Debug창을 열어야 합니다.

command + D 를 누르게 되면 아래와 같은 화면이 나타나는데, 이곳에서 Debug in Chrome을 클릭하면, Chrome창이 열립니다. 이곳에서 크롬 개발자 도구를 이용하여 console.log()를 통해 출력되는 값을 확인 할 수 있습니다.

nickname을 입력하고 Login버튼을 클릭하면 다음과 같이 정상적으로 값이 출력되는 것을 확인 할 수 있습니다.

2-4) SendBird에 Login하기

센드버드의 JavaScript SDK를 이용하기 위해 다음과 같이 선언하도록 하겠습니다.

var React = require('react-native');
var {
  View,
  Text,
  TextInput,
  TouchableHighlight,
  StyleSheet
} = React;

var sendbird = require(‘sendbird’);

module.exports = React.createClass({
getInitialState: function() {
return {
username: ”
};
},

그리고, onPress 함수를 다음과 같이 수정하도록 하겠습니다.

onPress: function() {
  sendbird.init({
    app_id: 'A7A2672C-AD11-11E4-8DAA-0A18B21C2D82',
    guest_id: this.state.username,
    user_name: this.state.username,
    image_url: "",
    access_token: "",
    successFunc: (data) => {
      console.log('success');
    },
    errorFunc: (status, error) => {
      this.setState({username: ''});
    }
  });
}

이곳에서 사용된 app_id는 현재 센드버드에서 샘플로 사용되고 있는 app_id입니다. 센드버드에서 새로운 Application을 생성하고 제공되는 app_id를 이용하셔도 무방합니다.

새로고침 후, nickname을 입력하고 Login버튼을 클릭하면 정상적으로 ‘success’가 출력되는 것을 확인 할 수 있습니다.

3) 채널 목록 만들기

이번에는 채널의 목록을 출력하는 화면을 만들어 보도록 하겠습니다.

3-1) 화면 구성하기

src/components/에 channels.js 파일을 생성한 후, 다음과 같이 수정하도록 하겠습니다.

var React = require('react-native');
var {
  View,
  Text,
  StyleSheet
} = React;

var sendbird = require(‘sendbird’);

module.exports = React.createClass({
render: function() {
return (
<View style={styles.container}>
<Text style={{color: ‘#fff’}}>Channels</Text>
</View>
);
}
});

var styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: ‘center’,
alignItems: ‘stretch’,
backgroundColor: ‘#6E5BAA’
}
});

main.js 파일에서 지금 생성된 channels.js를 ROUTES에 추가하도록 하겠습니다.

var Login = require('./components/login');
var Channels = require('./components/channels');

var ROUTES = {
login: Login,
channels: Channels
};

login.js파일의 onPress함수를 다음과 같이 수정하여, 클릭시 channels가 나타나도록 하겠습니다.

onPress: function() {
  sendbird.init({
    app_id: 'A7A2672C-AD11-11E4-8DAA-0A18B21C2D82',
    guest_id: this.state.username,
    user_name: this.state.username,
    image_url: "",
    access_token: "",
    successFunc: (data) => {
      this.props.navigator.push({ name: 'channels' });
    },
    errorFunc: (status, error) => {
      this.setState({username: ''});
    }
  });
}

시뮬레이터를 새로고침 한 후, nickname을 입력하고 Login 버튼을 클릭하면, 애니메이션과 함께 다음과 같은 화면이 나타나는 것을 확인 할 수 있습니다.

3-2) 채널 목록 가져오기

JavaScript SDK의 함수를 이용해서 채널의 목록을 가져와서 출력하는 화면을 만들어 보겠습니다.

channels.js파일을 다음과 같이 수정합니다.

var React = require('react-native');
var {
  View,
  Text,
  Image,
  TextInput,
  ListView,
  TouchableHighlight,
  StyleSheet
} = React;

var sendbird = require(‘sendbird’);
var PULLDOWN_DISTANCE = 40;

module.exports = React.createClass({
getInitialState: function() {
var ds = new ListView.DataSource({rowHasChanged: (r1, r2) => r1 !== r2});
return {
channelList: [],
dataSource: ds.cloneWithRows([]),
page: 0,
next: 0,
channelName: ”
};
},
componentWillMount: function() {
this.getChannelList(1);
},
render: function() {
return (
<View style={styles.container}>
<View style={styles.listContainer}>
<ListView
dataSource={this.state.dataSource}
renderRow={(rowData) =>
<TouchableHighlight onPress={() => this.onChannelPress(rowData.channel_url)}>
<View style={styles.listItem}>
<View style={styles.listIcon}>
<Image style={styles.channelIcon} source={{uri: rowData.cover_img_url}} />
</View>
<View style={styles.listInfo}>
<Text style={styles.titleLabel}># {rowData.name}</Text>
<Text style={styles.memberLabel}>{rowData.member_count} members</Text>
</View>
</View>
</TouchableHighlight>
}
onEndReached={() => this.getChannelList(this.state.next)}
onEndReachedThreshold={PULLDOWN_DISTANCE}
/>
</View>
</View>
);
},
onChannelPress: function(url) {
console.log(url);
},
getChannelList: function(page) {
if (page == 0) {
return;
}
sendbird.getChannelList({
page: page,
limit: 20,
successFunc : (data) => {
this.setState({channelList: this.state.channelList.concat(data.channels)}, () => {
this.setState({
dataSource: this.state.dataSource.cloneWithRows(this.state.channelList),
page: data.page,
next: data.next
});
});
},
errorFunc: (status, error) => {
console.log(status, error);
}
});
}
});

var styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: ‘center’,
alignItems: ‘stretch’,
backgroundColor: ‘#ffffff’
},
listContainer: {
flex: 11,
justifyContent: ‘center’,
alignItems: ‘stretch’,
marginTop: 10
},
listItem: {
flex: 1,
flexDirection: ‘row’,
justifyContent: ‘center’,
alignItems: ‘center’,
backgroundColor: ‘#f7f8fc’,
borderBottomWidth: 0.5,
borderColor: ‘#D0DBE4’,
padding: 5
},
listIcon: {
justifyContent: ‘flex-start’,
paddingLeft: 10,
paddingRight: 15
},
channelIcon: {
width: 30,
height: 30
},
listInfo: {
flex: 1,
justifyContent: ‘flex-start’
},
titleLabel: {
fontSize: 15,
fontWeight: ‘600’,
color: ‘#60768b’,
},
memberLabel: {
fontSize: 13,
fontWeight: ‘400’,
color: ‘#abb8c4’,
}
});

화면을 확인해보면, 채널의 목록들이 나타나는 것이 확인이 됩니다. 스크롤을 아래로 내리면, onEndReached에 등록된 getChannelList함수에 의해 다음 페이지의 채널 목록들이 이어 나오는 것이 확인이 되며, 채널을 클릭하면 채널의 url이 출력되는 것까지 확인이 됩니다.

다음과 같은 화면이 나타나며, 위의 기능들이 정상적으로 동작하면 문제가 없는 것입니다.

3-3) 채널 입장하기

channels.js파일의 onChannelPress함수를 다음과 같이 수정하겠습니다.

onChannelPress: function(url) {
  sendbird.joinChannel(
    url,
    {
      successFunc: (data) => {
        sendbird.connect({
          successFunc: (data) => {
            sendbird.getChannelInfo((channel) => {
              console.log(channel);
            });
          },
          errorFunc: (status, error) => {
            console.log(status, error);
          }
        });
      },
      errorFunc: (status, error) => {
        console.log(status, error);
      }
    }
  );
},

크롬 개발자도구를 이용하여 채널 입장 후 해당 채널의 정보를 출력해 볼 수 있습니다.

4) 채팅 화면

이번에는 채팅 화면을 만들어 보겠습니다. 간단하게 메시지가 오고 가는 부분만 확인하기 위해 텍스트 기반의 메시지로만 테스트를 진행하겠습니다.

4-1) 화면 구성하기

src/components/에 chat.js파일을 생성한 후 다음과 같이 수정합니다.

var React = require('react-native');
var {
  View,
  Text,
  StyleSheet
} = React;

var sendbird = require(‘sendbird’);

module.exports = React.createClass({
render: function() {
return (
<View style={styles.container}>
<Text style={{color: ‘#fff’}}>Chat</Text>
</View>
);
}
});

var styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: ‘center’,
alignItems: ‘stretch’,
backgroundColor: ‘#6E5BAA’
}
});

main.js 파일에 있는 ROUTES에 지금 만든 chat을 등록합니다.

var Login = require('./components/login');
var Channels = require('./components/channels');
var Chat = require('./components/chat');

var ROUTES = {
login: Login,
channels: Channels,
chat: Chat
};

채널을 클릭했을때, 현재 생성한 chat이 나타나도록 channels.js 파일에 있는 onChannelPress함수를 다음과 같이 수정하도록 하겠습니다.

onChannelPress: function(url) {
  sendbird.joinChannel(
    url,
    {
      successFunc: (data) => {
        sendbird.connect({
          successFunc: (data) => {
            sendbird.getChannelInfo((channel) => {
              this.props.navigator.push({ name: 'chat' });
            });
          },
          errorFunc: (status, error) => {
            console.log(status, error);
          }
        });
      },
      errorFunc: (status, error) => {
        console.log(status, error);
      }
    }
  );
}

이제 채널을 선택하면 지금 생성한 chat화면이 나타나는 것을 확인 할 수 있습니다.

4-2) 뒤로가기 버튼과 입력창

이번에는 상단에 ‘뒤로가기’버튼과 하단에 채팅 메시지를 입력하는 창을 구성해 보도록 하겠습니다.

chat.js 파일을 다음과 같이 수정하도록 하겠습니다.

  ...
  module.exports = React.createClass({
    render: function() {
      return (
        <View style={styles.container}>
          <View style={styles.topContainer}>
            <TouchableHighlight
              underlayColor={'#4e4273'}
              onPress={this.onBackPress}
              style={{marginLeft: 15}}
              >
              <Text style={{color: '#fff'}}>&lt; Back</Text>
            </TouchableHighlight>
          </View>
          <View style={styles.chatContainer}>
            <Text style={{color: '#000'}}>Chat</Text>
          </View>
          <View style={styles.inputContainer}>
            <Text style={{color: '#000'}}>Input</Text>
          </View>
        </View>
      );
    },
    onBackPress: function() {
      this.props.navigator.pop();
    }
  });

var styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: ‘center’,
alignItems: ‘stretch’,
backgroundColor: ‘#ffffff’
},
topContainer: {
flex: 1,
flexDirection: ‘row’,
justifyContent: ‘flex-start’,
alignItems: ‘center’,
backgroundColor: ‘#6E5BAA’,
paddingTop: 20,
},
chatContainer: {
flex: 11,
justifyContent: ‘center’,
alignItems: ‘stretch’
},
inputContainer: {
flex: 1,
justifyContent: ‘center’,
alignItems: ‘stretch’
}
});

‘< Back’ 을 클릭하면 this.props.navigator.pop() 에 의해서 현재 화면이 pop()되고 그 아래 있던 channels화면이 나타나는 것을 확인 할 수 있습니다. chat화면은 다음과 같이 보여지게 됩니다.

이번에는 메시지 입력창과 ‘SEND’ 버튼을 만들어 보겠습니다.

var React = require('react-native');
var {
  View,
  Text,
  TouchableHighlight,
  TextInput,
  Dimensions,
  StyleSheet
} = React;

var sendbird = require(‘sendbird’);
var windowSize = Dimensions.get(‘window’);

module.exports = React.createClass({
getInitialState: function() {
return {
message: ”
};
},
render: function() {
return (
<View style={styles.container}>
<View style={styles.topContainer}>
<TouchableHighlight
underlayColor={‘#4e4273’}
onPress={this.onBackPress}
style={{marginLeft: 15}}
>
<Text style={{color: ‘#fff’}}>&lt; Back</Text>
</TouchableHighlight>
</View>
<View style={styles.chatContainer}>
<Text style={{color: ‘#000’}}>Chat</Text>
</View>
<View style={styles.inputContainer}>
<View style={styles.textContainer}>
<TextInput
style={styles.input}
value={this.state.message}
onChangeText={(text) => this.setState({message: text})}
/>
</View>
<View style={styles.sendContainer}>
<TouchableHighlight
underlayColor={‘#4e4273’}
onPress={() => this.onSendPress()}
>
<Text style={styles.sendLabel}>SEND</Text>
</TouchableHighlight>
</View>
</View>
</View>
);
},
onBackPress: function() {
this.props.navigator.pop();
},
onSendPress: function() {
console.log(this.state.message);
this.setState({message: ”});
}
});

var styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: ‘center’,
alignItems: ‘stretch’,
backgroundColor: ‘#ffffff’
},
topContainer: {
flex: 1,
flexDirection: ‘row’,
justifyContent: ‘flex-start’,
alignItems: ‘center’,
backgroundColor: ‘#6E5BAA’,
paddingTop: 20,
},
chatContainer: {
flex: 11,
justifyContent: ‘center’,
alignItems: ‘stretch’
},
inputContainer: {
flex: 1,
flexDirection: ‘row’,
justifyContent: ‘space-around’,
alignItems: ‘center’,
backgroundColor: ‘#6E5BAA’
},
textContainer: {
flex: 1,
justifyContent: ‘center’
},
sendContainer: {
justifyContent: ‘flex-end’,
paddingRight: 10
},
sendLabel: {
color: ‘#ffffff’,
fontSize: 15
},
input: {
width: windowSize.width – 70,
color: ‘#555555’,
paddingRight: 10,
paddingLeft: 10,
paddingTop: 5,
height: 32,
borderColor: ‘#6E5BAA’,
borderWidth: 1,
borderRadius: 2,
alignSelf: ‘center’,
backgroundColor: ‘#ffffff’
},
});

메시지를 입력하고 ‘SEND’를 클릭하면 입력한 메시지가 출력되는 것을 다음과 같이 확인 할 수 있습니다.

이번에는 Dismensions가 추가적으로 사용되었습니다.

4-3) 채팅 주고 받기

마지막으로 채팅을 주고 받는 기능을 구현하도록 하겠습니다. 현재 사용되고 있는 센드버드의 Application은 샘플로 사용되고 있으며 웹 샘플에서도 같은 app_id를 사용하고 있습니다. 우리는 웹 샘플과 비교를 하며 확인을 하도록 하겠습니다. [웹 샘플 다운로드]

getInitialState를 다음과 같이 수정하겠습니다.

getInitialState: function() {
  return {
    message: '',
    messageList: []
  };
},

componentWillMount를 추가하고 다음과 같이 작성하도록 하겠습니다.

componentWillMount: function() {
  sendbird.events.onMessageReceived = (obj) => {
    this.setState({messageList: this.state.messageList.concat([obj])});
  };
  this.getMessages();
},

getMessages함수를 다음과 같이 수정하도록 하겠습니다.

getMessages: function() {
  sendbird.getMessageLoadMore({
    limit: 100,
    successFunc: (data) => {
      var _messageList = [];
      data.messages.reverse().forEach(function(msg, index){
        if(sendbird.isMessage(msg.cmd)) {
          _messageList.push(msg.payload);
        }
      });
      this.setState({ messageList: _messageList.concat(this.state.messageList) });
    },
    errorFunc: (status, error) => {
      console.log(status, error);
    }
  });
}

onSendPress 함수를 다음과 같이 수정하도록 하겠습니다.

onSendPress: function() {
  sendbird.message(this.state.message);
  this.setState({message: ''});
},

onBackPress함수를 다음과 같이 수정하도록 하겠습니다.

onBackPress: function() {
  sendbird.disconnect();
  this.props.navigator.pop();
},

render 함수를 다음과 같이 수정하도록 하겠습니다.

render: function() {
  var list = this.state.messageList.map((item, index) => {
    return (
      <View
        style={styles.messageContainer}
        key={index}
        >
        <Text style={this.nameLabel}>
          {item.user.name}
          <Text style={styles.messageLabel}> : {item.message}</Text>
        </Text>
      </View>
    );
  });

return (
<View style={styles.container}>
<View style={styles.topContainer}>
<TouchableHighlight
underlayColor={‘#4e4273’}
onPress={this.onBackPress}
style={{marginLeft: 15}}
>
<Text style={{color: ‘#fff’}}>&lt; Back</Text>
</TouchableHighlight>
</View>
<View style={styles.chatContainer}>
<ScrollView
ref={(c) => this._scrollView = c}
onScroll={this.handleScroll}
scrollEventThrottle={16}
onContentSizeChange={(e) => {}}
>
{list}
</ScrollView>
</View>
<View style={styles.inputContainer}>
<View style={styles.textContainer}>
<TextInput
style={styles.input}
value={this.state.message}
onChangeText={(text) => this.setState({message: text})}
/>
</View>
<View style={styles.sendContainer}>
<TouchableHighlight
underlayColor={‘#4e4273’}
onPress={() => this.onSendPress()}
>
<Text style={styles.sendLabel}>SEND</Text>
</TouchableHighlight>
</View>
</View>
</View>
);
},

마지막으로, 선택한 채널에 접속하기 위해 channels.js 파일에 있는 onChannelPress함수를 다음과 같이 수정하도록 하겠습니다.

onChannelPress: function(url) {
  sendbird.joinChannel(
    url,
    {
      successFunc: (data) => {
        sendbird.connect({
          successFunc: (data) => {
            sendbird.getChannelInfo((channel) => {
              sendbird.connect({
                successFunc: (data) => { this.props.navigator.push({ name: 'chat' }); },
                errorFunc: (status, error) => { console.log(status, error); }
              });
            });
          },
          errorFunc: (status, error) => {
            console.log(status, error);
          }
        });
      },
      errorFunc: (status, error) => {
        console.log(status, error);
      }
    }
  );
},

웹 샘플을 통해 같은 채널에 입장 후 메시지가 오고 가는 것을 확인 할 수 있습니다.


이번 글을 통해 소개한 것 외에도 다양한 기능이 JavaScript SDK에 있습니다. 더 자세한 내용은 JavaScript SDK 문서를 통해 확인이 가능하며, 해당 문서를 통해 센드버드의 JavaScript SDK를 원활히 이용하는데 도움이 되시길 바랍니다. 이번 샘플 프로젝트보다 조금 더 다양한 기능을 이용하여 제작된 샘플도 다운로드가 가능하십니다. [샘플 다운로드 받기]

React Native에 대해 많은 내용과 자세한 설명을 해드리고 싶었으나, 제한된 공간때문에 가볍게 체험하는 형식으로 설명을 드리게 되었습니다. React Native의 공식문서를 참고하시어 더욱 많은 기능을 이용하여 여러분들이 만들어 보고자 했던 멋진 앱을 제작해 보시길 바랍니다.

프로젝트를 진행하며 궁금한 점이나 문의 사항은 support@sendbird.com으로 전달해 주시면 빠르고 정확한 안내를 통해 도움을 드리겠습니다. 감사합니다.

Tags: Engineering