ReactとFirebaseで一から地道にチャット掲示板を作っていく
ReactとFirebaseで一から地道にチャット掲示板を作っていく:
Reactビギナーがウェブサービスを作っていく過程を公開していこうと思います。
アイディアとしては、リアルタイムチャットが出来る掲示板を目指していこうかと考えています。
今回は、Reactのセットアップと以下の様な簡易的なチャット機能を作ろうと思います。
開発中のレポジトリはこちらになります https://github.com/ychino/craigschat
最新の動いているアプリはこちらです https://craigschat-230e6.firebaseapp.com/
まずはcreate-react-appをローカルにインストールします。
お好きなディレクトリに移動し、Reactプロジェクトを作成します。現時点ではcraigslistのような掲示板でさらにslackのようなチャット機能を持ち合わせたものを構想しているので、craigschatという名前でいきたいと思います。
そして、http://localhost:3000/ にアクセスすると、、、タラーン!いいですね。無事動いているようです。
まずは、チャットに必要なコメントを入力するボックスを作っていきたいと思います。
現時点で以下の様な構成となっています。
そして、このコメントボックスコンポーネントをインポートし、表示するため
いい感じです。コメントボックスが表示されました。
続いて、コメントの投稿機能を作って行きたいと思います。とりあえず、
ここで行っていることは、
最後にrenderメソッド内で
CommentBox.jsを変更していきます。上記で
CommentBoxのフィールドからテキストが入力され、
さぁ、最後に
次回は、Firebaseを使ってデータを永続化していきたいと思います。では!
Reactビギナーがウェブサービスを作っていく過程を公開していこうと思います。
アイディアとしては、リアルタイムチャットが出来る掲示板を目指していこうかと考えています。
今回は、Reactのセットアップと以下の様な簡易的なチャット機能を作ろうと思います。
開発中のレポジトリはこちらになります https://github.com/ychino/craigschat
最新の動いているアプリはこちらです https://craigschat-230e6.firebaseapp.com/
Reactアプリケーションの作成
まずはcreate-react-appをローカルにインストールします。npm install -g create-react-app
create-react-app cragschat cd craigschat npm start
チャット機能を作っていく
まずは、チャットに必要なコメントを入力するボックスを作っていきたいと思います。現時点で以下の様な構成となっています。
src配下にcomponentsフォルダを作成し、その下にCommentBox.jsを作成しました。// CommentBox.js
import React from 'react';
export const CommentBox = (props) => (
<div>
<input
name='userName'
placeholder='username'
/>
<textarea
name='text'
placeholder="comment"
/>
<button>Comment</button>
</div>
)
App.jsを以下の様に変更します。// App.js
import React, { Component } from 'react';
import { CommentBox } from './components/CommentBox'
import './App.css';
class App extends Component {
render() {
return (
<div className="App">
<h1>Chat</h1>
<CommentBox />
</div>
);
}
}
export default App;
続いて、コメントの投稿機能を作って行きたいと思います。とりあえず、
App.jsのstateとしてコメントを保存していきたいと思いますので、App.jsを以下の様に変更します。 ここで行っていることは、
App.jsにuserName及びtextを保存する為のstateを設定し、CommentBox.jsのフォームから渡される値をstateへ保存するためのonTextChangeメソッドを設定しています。this.onTextChange = this.onTextChange.bind(this);を忘れずに。bind(this)って何?って方はこちらをご参照ください(https://reactjs.org/docs/handling-events.html) 。最後にrenderメソッド内で
CommentBoxコンポーネントにtext/userName state及びonTextChangeメソッドをpropsとして渡します。// App.js
import React, { Component } from 'react';
import { CommentBox } from './components/CommentBox'
import './App.css';
class App extends Component {
constructor(props) {
super(props);
this.state = {
userName: "",
text : "",
}
this.onTextChange = this.onTextChange.bind(this);
}
onTextChange(e) {
if(e.target.name === 'userName') {
this.setState({
userName : e.target.value,
});
} else if (e.target.name === 'text') {
this.setState({
text : e.target.value,
});
}
}
render() {
return (
<div className="App">
<h1>Chat</h1>
<CommentBox text={this.state.text} userName={this.state.userName} onTextChange={this.onTextChange} />
</div>
);
}
}
export default App;
CommentBoxコンポーネントに渡されたpropsはpropsとして以下コンポーネントに渡されます。親コンポーネントから渡されたpropsはprops.usernameのようにして子コンポーネント内で参照できます。// CommentBox.js
import React from 'react';
export const CommentBox = (props) => (
<div>
<input
name='userName'
placeholder='username'
value={props.userName}
onChange={props.onTextChange}
/>
<textarea
name='text'
placeholder="comment"
value={props.text}
onChange={props.onTextChange}
/>
<button>Comment</button>
</div>
)
Inputとtextareaそれぞれvalueが変更されると、親コンポーネントからonChangeイベントハンドラーに渡されたonTextChangeが呼ばれ、this.setState()を用いて、Appコンポーネントのstateにそれぞれ保存されます。onTextChangeにはSyntheticEventと呼ばれ、引数eにそれぞれのvalueが渡されます(以下のコード内のようにメソッド内からe.target.valueのように参照できます)。SyntheticEvent - https://reactjs.org/docs/events.html
App.jsに戻り、userNameとtextをまとめてメッセージオブジェクトとするとし、そのオブジェクトを格納する配列massagesを保存するmessages stateとCommentBoxのボタンがクリックすると呼ばれるonButtonClick()を追加し、CommentBoxへpropsとして渡します。onButtonClick()では、まず、initial stateである空のmessages配列を参照し、userNameとtext stateをオブジェクトとしてまとめて配列にpushしています。// App.js
class App extends Component {
constructor(props) {
super(props);
this.state = {
userName: "",
text : "",
messages : []
}
this.onTextChange = this.onTextChange.bind(this);
this.onButtonClick = this.onButtonClick.bind(this);
}
onTextChange(e) {
if(e.target.name === 'userName') {
this.setState({
userName : e.target.value,
});
} else if (e.target.name === 'text') {
this.setState({
text : e.target.value,
});
}
}
onButtonClick() {
const currentMessages = this.state.messages;
currentMessages.push({userName: this.state.userName, text: this.state.text})
this.setState({messages: currentMessages});
}
render() {
return (
<div className="App">
<h1>Chat</h1>
{this.state.messages.map((m) => <h5>{m.userName}</h5>)}
<CommentBox text={this.props.text} userName={this.props.userName} onTextChange={this.onTextChange} onButtonClick={this.onButtonClick}/>
</div>
);
}
}
export default App;
CommentBox.jsのonClickにonButtonClickを設定します。<button onClick={props.onButtonClick}>Comment</button>
App.jsのmessages stateに保存されているmessageをそれぞれ表示してみましょう。renderメソッドに配列messageの要素をひとつずつ表示する{this.state.messages.map((m) => <h5>{m.userName}</h5>)}を追加しました。また、App.jsのonButtonClickにボタンクリック後、フィールドをそれぞれクリアするためのthis.setState({userName: "", text: ""})を追加しました。....
onButtonClick() {
const currentMessages = this.state.messages;
currentMessages.push({userName: this.state.userName, text: this.state.text})
this.setState({messages: currentMessages});
this.setState({userName: "", text: ""})
}
render() {
return (
<div className="App">
<h1>Chat</h1>
{this.state.messages.map((msg, id) => <h5 key={id}>@{msg.userName}, {msg.text}</h5>)}
<CommentBox text={this.state.text} userName={this.state.userName} onTextChange={this.onTextChange} onButtonClick={this.onButtonClick}/>
</div>
);
}
....
コメント
コメントを投稿