react-select
前回は redux-form について触れました。
今回は react-select について触れます。
目次
- 開発環境を準備
- React の基本的な Life Cycle に触れる
- redux に触れる
- redux-saga に触れる
- react router に触れる
- npm で公開されている components を導入して echo system を体感する
- redux-form に触れる
- react-select に触れる <= 今日やること
今日やること
準備
npm install --save react-select
各種ファイル作成
touch src/components/Form.js
create src/components/Form.js
import React, { Component } from 'react'
import { Field, reduxForm } from 'redux-form'
import Select from 'react-select'
import 'react-select/dist/react-select.css'
export const renderField = ({ input, label, type, meta: { touched, error } }) => (
<div className="form-group">
<label htmlFor={label}>{label}</label>
<input className="form-control" {...input} placeholder={label} type={type}/>
<p className="text-danger">{touched && (error && <span>{error}</span>)}</p>
</div>
)
export const renderTextAreaField = ({ input, label, type, meta: { touched, error } }) => (
<div className="form-group">
<label htmlFor={label}>{label}</label>
<textarea className="form-control" {...input} placeholder={label} type={type} rows="10"/>
<p className="text-danger">{touched && (error && <span>{error}</span>)}</p>
</div>
)
export const renderSelectField = ({ input, label, options, meta: { touched, error } }) => {
return (
<div className="form-group">
<label htmlFor={label}>{label}</label>
<Select
name={input.name}
value={input.value}
onChange={input.onChange}
onBlur={() => input.onBlur(input.value)}
options={options}
placeholder="Select"
simpleValue
clearable={false}
/>
<p className="text-danger">{touched && (error && <span>{error}</span>)}</p>
</div>
)
}
export const renderSelectMultiField = ({ input, label, options, meta: { touched, error } }) => {
return (
<div className="form-group">
<label htmlFor={label}>{label}</label>
<Select
{...input}
onBlur={() => input.onBlur([...input.value].map(x => (x.value)))}
options={options}
multi
/>
<p className="text-danger">{touched && (error && <span>{error}</span>)}</p>
</div>
)
}
edit src/containers/CreatePost.js
import React, {Component} from 'react'
import { connect } from 'react-redux'
import { Field, reduxForm } from 'redux-form'
import { createPost } from '../actions'
import { renderField, renderTextAreaField, renderSelectField, renderSelectMultiField } from '../components/Form'
const userOptions = [
{value: 1, label: "userOne"},
{value: 2, label: "userTwo"},
{value: 3, label: "userThuree"},
]
const tagsOptions = [
{value: "foo", label: "foo"},
{value: "bar", label: "bar"},
{value: "hoge", label: "hoge"},
{value: "fuga", label: "fuga"},
]
let PostForm = (props) => {
const { handleSubmit, pristine, submitting } = props
return (
<form onSubmit={handleSubmit}>
<Field name="userId" label="User" component={renderSelectField} options={userOptions} />
<Field name="title" type="text" label="Title" component={renderField} />
<Field name="tags" label="Tags" component={renderSelectMultiField} options={tagsOptions} />
<Field name="body" type="text" label="Body" component={renderTextAreaField} />
<div style={{marginTop: "30px"}}>
<button className="btn btn-primary" type="submit" disabled={pristine || submitting}>Submit</button>
</div>
</form>
)
}
const validate = values => {
const errors = {}
if (!values.title) {
errors.title = 'Required'
} else if (values.title.length > 15) {
errors.title = 'Must be 15 characters or less'
}
if (!values.body) {
errors.body = 'Required'
}
return errors
}
PostForm = reduxForm({
form: "post",
validate,
enableReinitialize: true,
})(PostForm)
class CreatePost extends Component {
handleSubmit() {
const params = this.props.form.post.values
// Note: the resource will not be really created on the server but it will be faked as if.
this.props.dispatch(createPost({params}))
}
render() {
return (
<PostForm onSubmit={this.handleSubmit.bind(this)} />
)
}
}
const select = state => (state)
export default connect(select)(CreatePost)
まとめ
以上全8回に分けて React.js で SPA の作り方を紹介しました。将来的に自分が React.js の事を忘れた時に備えた記事ですが、どこかで誰かの役に立てばうれしいです。
なのですがそういえば DatePicker の事を書くのを忘れていました。
ということであとちょっとだけ続きます。