Skip to content

Instantly share code, notes, and snippets.

@suhaotian
Last active November 1, 2016 01:21
Show Gist options
  • Save suhaotian/17473d75b6a5aa6376300572646051bb to your computer and use it in GitHub Desktop.
Save suhaotian/17473d75b6a5aa6376300572646051bb to your computer and use it in GitHub Desktop.
import React, { Component, PropTypes } from 'react'
export default class Field extends Component {
constructor(props, context) {
super(props, context)
const {
name, type, value, checked
} = props
this.is_checkbox = type === 'checkbox'
this.is_radio = type === 'radio'
this.data = {}
this.data[name] = this.is_checkbox ? checked : value
this.state = this.data
this.handleChange = this.handleChange.bind(this)
}
componentDidMount() {
const {name, value, checked, defaultChecked} = this.props
let handleChange = null
if (this.is_checkbox) {
handleChange = () => {
this.context.data[name] = this.data[name] = !this.data[name]
this.setState(this.data)
}
this.context.data[name] = checked
} else {
handleChange = (e) => {
this.context.data[name] = this.data[name] = e.target.value
if (this.is_radio) return
this.setState(this.data)
}
this.context.data[name] = (
this.is_radio && !defaultChecked ?
this.context.data[name] : value
)
}
this.emit_name = (
this.context.event.cbs[name] ?
`${name}:${this.context.event.cbs[name].length}` :
name
)
this.context.event.on(this.emit_name, handleChange)
}
componentWillReceiveProps(nextProps) {
this.is_checkbox = nextProps.type === 'checkbox'
this.is_radio = nextProps.type === 'radio'
}
componentWillUnmount() {
this.context.event.off(this.emit_name)
}
handleChange(e) {
this.context.event.emit(this.emit_name, e)
}
render() {
const {
component: TempComponent, ...rest
} = this.props
rest[this.is_checkbox ? 'checked' : 'value'] = this.state[this.props.name]
return (
<TempComponent
{...rest}
onChange={this.handleChange}
/>
)
}
}
Field.contextTypes = {
event: PropTypes.object.isRequired,
data: PropTypes.object.isRequired,
}
Field.propTypes = {
name: PropTypes.string.isRequired,
value: PropTypes.any,
checked: PropTypes.bool,
component: PropTypes.string.isRequired,
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment