#ReactにおけるDatePickerとmoment
React Bootstrap DatePickerは日付をフォームに入力する際にカレンダーを表示させて、カレンダーの日付をクリックすると選択した日付がフォームに入る機能。
これを使うためには、react-bootstrap-date-pickerをインストールする。
npm install react-bootstrap-date-picker --save
また、以下のようにimportする。
import DatePicker from 'react-datepicker'
import 'react-datepicker/dist/react-datepicker.css’
moment()は時刻をDate型で取得する関数。
何も渡さずに行うと、Date型で現在の時刻を返す。
UTCミリ秒を渡した場合は、Date型に変換して返す。
- UTCは1970年1月1日00:00:00から経過した時間をミリ秒単位で表したもの
moment()を使うには、以下をimportする。
import moment from 'moment'
DatePicker&moment記述例
this.state = {
sample: moment()
}
DatehandleChange_sample(date) {
this.setState({ sample: date })
}
<DatePicker
selected={this.state.sample}
name=“sample”
value={this.state.sample}
onChange={(e) => this.DatehandleChange_sample(e)}
/>
デフォルトだと01/01/2017のように、年が後ろに表示されるので、以下のようにコンストラクタなどでロケールをjaにするとよい。
moment.locale('ja')
と書いておくと2017/01/01の表記になる。
DatePickerで定義されたフォームのvalue(上記のvalue={this.state.sample}
)を直接指定して取れるのはDate型ではなく、フォームに入力されている日付が文字列で取り出される。
(フォームに2017/01/01と表示されていたら、「2017/01/01」という文字列が取り出される)
もしDatePickerで定義したフォームのvalueに文字列を入れて、内容を更新しようとした場合以下の警告が出る
moment.js:293 Deprecation warning: value provided is not in a recognized RFC2822 or ISO format. moment construction falls back to js Date(), which is not reliable across all browsers and versions. Non RFC2822/ISO date formats are discouraged and will be removed in an upcoming major release. Please refer to http://momentjs.com/guides/#/warnings/js-date/ for more info.
この状態だとカレンダーは出るが、カレンダーの日付をクリックすると、エラーが出る。
Uncaught TypeError: we.isSame is not a function
このエラーが出るのは、DatePickerの変数はDate型で無ければならないため。
文字列をDate型に変換したい場合は、以下のように、Date.parse()やgetTime()を使ってUTCミリ秒に変換した数値をmoment()に渡す必要がある。
state = { sample: '2017/01/01" }
moment(Date.parse( this.state.sample ) )//UTCミリ秒に変更した数値をmomentに渡している
明細行にDatePickerが含まれ、それが動的に追加される処理などの場合、変数と一緒に関数も同時に生成する必要があった。ソースコード
//stateで行を管理するrowsを作成
this.state ={
rows: [1]
}
>
//
this.setReturn_date = []
this.setReturn_date[0] = function (date) {
this.setState({ return_date1: date })
}.bind(this)
>
addRow() {
this.setState(
(prevState) => ({
rows: prevState.rows.concat([prevState.rows.length + 1])
})
)
const return_date = 'return_date' + (this.state.rows.length + 1)
this.setReturn_date[this.state.rows.length] = function (date) {
this.setState({ [return_date]: date })
}.bind(this)
}
>
HobbyForm(row: number) {
const return_date = 'return_date' + row
return(
<tbody key={row.toString()}>
<td>
<Col sm={12}>
<FormGroup controlId={return_date}>
<DatePicker selected={this.state[return_date]}
name={return_date}
value={this.state[return_date]}
onChange={(e) => this.setReturn_date[row-1](e)} />
</FormGroup>
</Col>
</td>
</tbody>
)
}
#Reactにおけるラジオボタン
ラジオボタンを使うには、以下をimportする。
import React from 'react'
import Radio from 'react-bootstrap'
記述例
state = { sample:''}
RadioChange(e:InputEvent){
this.setState({ sample: e.target.id })
}
<FormGroup controlId="publication">
<Col xs={10}sm={10}md={10}lg={10}xl={10}>
<Radio id="sample1" name="sample_name" checked={this.state.sample === 'sample1'} onChange={(e) => this.RadioChange(e)} inline>SAMPLE1</Radio>
<Radio id="sample2" name="sample_name" checked={this.state.sample === 'sample2'} onChange={(e) => this.RadioChange(e)} inline>SAMPLE2</Radio>
<Radio id="sample3" name="sample_name" checked={this.state.sample === 'sample3'} onChange={(e) => this.RadioChange(e)} inline>SAMPLE3</Radio>
</Col>
</FormGroup>
- ReactのRadioボタンでは、checkedがtrueかfalseでチェックされているかどうかを判断する。
- this.state.sampleに最後に押されたボタンを管理させる。
- sample1のRadioボタンが押されていたら、this.state.sampleにはsample1が入り、{this.state.sample ==='sample1}が成立してtrueになる。
#JSONのキーが変数のときは[]でくくる。
setStateなどでhoge変数のキーを変更するときは
setState( { [hoge]:true } )
のように[]で括る。
#stateの孫の変数の変更方法
stateの子を変更するときは
this.setState({children:1}) //OK
で変更可能、しかしstateの孫の変数をsetStateで直接変更をすることは出来ない。
this.setState({children.gChildren:2}) //NG
孫の変数をsetStateで変えたいときは、以下のように関数を呼んで子の中身全体を変える。
this.state = {feed : {}}
1 this.setState(
2 (prevState) => //ここのprevStateを16行目のprevStateに渡す
3 ({feed: ((prevState) => { //16行目のprevStateを受取り、以下の処理
4 if (!prevState.feed.entry[0].bill.items) {
5 prevState.feed.entry[0].bill.items = []
6
7 }
8 prevState.feed.entry[0].bill.items.push({
9 brand_name: '',
10 item_no: '',
11 item_name: '',
12 usage_situation: '',
13 return_date: moment(),
14 })
15 return prevState.feed
16 })(prevState)//ここのprevStateを3行目のprevStateに渡す
17 })
18)