Node.js + React
メモ
- 3-5から開始
- 正規表現は勉強しといた方が良さそう。
- プロパティの型の定義を学んだ
- FormInputというコンポーネントで、valueとnameとfilter, onChangeという4つのプロパティを利用できるものとする例
class FormInput extends Component {...}
import PropTypes from 'prop-types'
FormInput.propTypes = {
value: PropsTypes.string,
name: PropsTypes.string.isRequired,
filter: PropsTypes.object,
onChange: PropTypes.func
}
FormInput.defaultProps = {
filter: null,
pattern: null,
value: '',
onChange: null
}
import React, {Component} from 'react'
import PropTypes from 'prop-types'
export default class FormInput extends Component {
constructor (props) {
super(props)
const v = this.props.value
this.state = {
value: v,
isOK: this.checkValue(v)
}
}
checkValue (s) {
if (this.props.pattern === null) {
return true
}
return this.props.pattern.test(s)
}
handleChange (e) {
const v = e.target.value
const filter = this.props.filter
let newValue = v
if (filter !== null){
newValue = newValue.replace(filter, '')
}
const newIsOK = this.checkValue(newValue)
this.setState({
value: newValue,
isOk: newIsOK
})
if(this.props.onChange) {
this.props.onChange({
target: this,
value: newValue,
isOK: newIsOK,
name: this.props.name
})
}
}
componentWillReceiveProps (nextProps) {
this.setState({
value: nextProps.value,
isOK: this.checkValue(nextProps.value)
})
}
render () {
const msg = this.renderStatusMessage()
return (<div>
<label>{this.props.label}: <br />
<input type="text"
name={this.props.name}
placeholder={this.props.placeholder}
value={this.state.value}
onChange={e => this.handleChange(e)} />
{msg}
</label>
</div>)
}
renderStatusMessage() {
const so = {
margin: '8px',
padding: '8px',
color: 'white'
}
let msg = null
if (this.state.isOK){
so.backgroundColor = 'green'
msg = <span style={so}>OK</span>
} else {
if (this.state.value !== ''){
so.backgroundColor = 'red'
msg = <span style={so}>NG</span>
}
}
return msg
}
}
FormInput.propType = {
name: PropTypes.string.isRequired,
label: PropTypes.string.isRequired,
filter: PropTypes.object,
pattern: PropTypes.object,
value: PropTypes.string,
placeholder: PropTypes.string,
onChange: PropTypes.func
}
FormInput.defaultProps = {
filter: null,
pattern: null,
value: '',
placeholder: '',
onChange: null
}
- DOMにReactで直接アクセスするにはrefプロパティを使う。このプロパティには、コールバック関数を指定するのだが、ReactがDOMを直接インスタンス化する際に実行される。コールバック関数が実行されるとき、インスタンス化したDOMオブジェクトが引数として得られる。
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="https://unpkg.com/react@15/dist/react.min.js"></script>
<script src="https://unpkg.com/react-dom@15/dist/react-dom.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/babel-core/5.8.38/browser.min.js"></script>
</head>
<body>
<div id="root"></div>
<script type="text/babel">
class LoginForm extends React.Component {
constructor (props){
super(props)
this.state = {
user: '',
pass: ''
}
}
render() {
const doSubmit = e => this.doSubmit(e)
const doChange = e => this.doChange(e)
return (<form onSubmit={doSubmit}>
<label>ユーザー名: <br />
<input type="text" name="user"
ref={ (i)=>{ this.user = i} }
value={this.state.user}
onChange={doChange} />
</label><br />
<label>パスワード: <br />
<input type="text" name="pass"
ref={ (i)=>{ this.pass = i} }
value={this.state.pass}
onChange={doChange} />
</label><br />
<input type="submit" value="送信" />
</form>)
}
doChange (e) {
const key = e.target.name
this.setState({
[key]: e.target.value
})
}
doSubmit (e) {
e.preventDefault()
if (!this.state.user) {
this.user.focus()
return
}
if (!this.state.pass) {
this.pass.focus()
return
}
window.alert(JSON.stringify(this.state))
}
}
ReactDOM.render(
<div><LoginForm /></div>,
document.getElementById('root')
)
</script>
</body>
</html>
- コンポーネントのrender()メソッドで返すオブジェクトは実際に、DOMに描画されるオブジェクトとは全く関係がない。Reactはrender()メソッドの戻り値を元にして、実際のDOMを生成するので、戻り値はDOMオブジェクトではないことに注意。
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="https://unpkg.com/react@15/dist/react.min.js"></script>
<script src="https://unpkg.com/react-dom@15/dist/react-dom.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/babel-core/5.8.38/browser.min.js"></script>
</head>
<body>
<div id="root"></div>
<script type="text/babel">
class MyCompo extends React.Component {
constructor(props){
super(props)
this.state = {value: ''}
}
render() {
this.preInput = <input
type="text"
ref={i => { this.realInput = i }}
onClick={e => this.doClick(e)} />
return (
<div>{this.preInput}</div>
)
}
doClick (e) {
console.log(this.preInput)
console.log(this.realInput)
if (this.preInput === this.realInput) {
console.log('同じ')
}else{
console.log('異なる')
}
}
}
ReactDOM.render(
<div><MyCompo /></div>,
document.getElementById('root')
)
</script>
</body>
</html>
SuperAgent(Ajax通信をするライブラリ)の使い方
- SuperAgentのライブラリを取り込む
- request.get(url).end(callback)を呼ぶ
- データを取得した時のコールバック関数を記述
const request = require('superagent')
const URL = 'http://localhost:3000/fruits.json'
request.get(URL)
.end(callbackGet)
function callbackGet (err, res) {
if(err) {
return
}
console.log(res.body)
}
機能を確認
- GETメソッドを送信する際にURLパラメータを指定したい場合にはquery()メソッドを呼び出す
const params = {q: 'search', uid: 100}
request.get(URL)
.query(params)
.end(callback)
request.get(URL)
.set('API-KEY', 'xxxxxxxx')
.end(callback)
- POSTメソッドを送信する場合にはget()ではなくpost()メソッドを呼び出す。この場合はsend()メソッドでパラメータを指定する。
request.protocols(URL)
.set('Content-Type', 'application/json')
.send( {name: 'hoge', age: 21})
.end(callback)
- URLパラメータを指定する場合にはquery()で行い、リクエスト本体にパラメータを指定する場合にはsend()メソッドを使う。
request.post(URL)
.set('Content-Type', 'application/json')
.query( {mode: 'aave', userid: 100})
.send( {name: 'hoge', age: 21})
.end(callback)