React Native (Expo) から Azure Functions と SignalR Service のクイック スタートのサンプルアプリを試してみた
クイック スタート:C# を使用した Azure Functions と SignalR Service によるチャット ルームの作成のクライアントテストアプリケーションを Expoで作成して試してみます。
記事の中で紹介されている サンプルのシングル ページ Web アプリケーション を React Native + Expo 用にちょっと書き直しです。
クリックスタートに従って、ブラウザで動くところまで準備して
- Azure SignalR Service作成
- サンプル アプリケーションの準備と実行
- Web アプリケーションで動作確認
クライアントを作成です。
Expo のプロジェクト作成 (TypeScript)とパッケージを必要なパッケージの追加
expo init chat cd chat npm i @microsoft/signalr npm i axios
あとは出来たプロジェクトのApp.tsxをちょい修正してサンプルアプリは完了。
import React from 'react' import { StyleSheet, Text, TextInput, Button, SafeAreaView, FlatList } from 'react-native' import { HubConnectionBuilder } from '@microsoft/signalr' import axios from 'axios' const name = 'ヤス' const apiBaseUrl = 'http://192.168.XXX.XXX:7071' export default class App extends React.Component { state:IState = { isReady: false, count: 1, text: '', messages: [] }; increment (): number { const count = this.state.count + 1 this.setState({ count: count }) return count } componentDidMount = () => { const hubConnection = new HubConnectionBuilder() .withUrl(`${apiBaseUrl}/api`) .build() hubConnection.onclose(() => console.log('disconnected')) hubConnection .start() .then(() => this.setState({ isReady: true })) hubConnection.on('newMessage', (m:IMessage) => { const key = this.increment() const messages = this.state.messages.slice() as Message[] const message = new Message(key.toString(), m.sender, m.text) messages.unshift(message) this.setState({ messages: messages }) }) } sendMessage = (text:string) => { axios.post(`${apiBaseUrl}/api/messages`, { sender: name, text: text }).then(_ => {}) this.setState({ text: '' }) } render () { if (!this.state.isReady) { return <SafeAreaView style={styles.container}> <Text>Connecting</Text> </SafeAreaView> } else { return <SafeAreaView style={styles.container}> <Text>Serverless Chat</Text> <TextInput style={styles.textBox} onChangeText={value => this.setState({ text: value })} value={this.state.text} /> <Button title="送信" onPress={() => { this.sendMessage(this.state.text) }} /> <FlatList data={this.state.messages} renderItem={({ item }) => <Text style={styles.item}> {item.sender} : {item.text} </Text>} /> </SafeAreaView > } } } class Message implements IMessage { key: string sender: string text: string constructor (key: string, sender: string, text: string) { this.key = key this.sender = sender this.text = text } } interface IMessage { sender: string text: string } interface IState { isReady: boolean count: number text: string messages: Message[] } const styles = StyleSheet.create({ container: { flex: 1 }, item: { padding: 10, height: 44 }, textBox: { height: 50, margin: 10, padding: 10, borderColor: 'gray', borderWidth: 1 } })
サンプルのシングル ページ Web アプリケーションと同じように動きました。