import React, { Component, PropTypes } from 'react';
import { connect } from 'react-redux'
import createFieldProps from './createFieldProps'
import bindActionData from './bindActionData'
const createField = ({ getIn }) => {
const createConnectedField = ({ blur, change, focus, getFormState }, name) => {
const actions = bindActionData({ blur, change, focus }, { field: name })
return connect(
state => ({
initial: getIn(getFormState(state), `initial.${name}`),
value: getIn(getFormState(state), `values.${name}`),
state: getIn(getFormState(state), `fields.${name}`)
})
)(({ component, ...props }) => {
const Component = component // gotta make this uppercase for some reason
return <Component {...createFieldProps(getIn, name, {...props, ...actions})}/>
})
}
class Field extends Component {
constructor(props, context) {
super(props, context)
if (!context._reduxForm) {
throw new Error('Field must be inside a component decorated with reduxForm()')
}
this.ConnectedField = createConnectedField(context._reduxForm, props.name)
}
componentWillReceiveProps(nextProps) {
if (this.props.name !== nextProps.name) {
// name changed, regenerate connected field
this.ConnectedField = createConnectedField(this.context._reduxForm, nextProps.name)
}
}
render() {
const { ConnectedField } = this
return <ConnectedField {...this.props}/>
}
}
Field.propTypes = {
name: PropTypes.string.isRequired,
component: PropTypes.func.isRequired
}
Field.contextTypes = {
_reduxForm: PropTypes.object
}
return Field
}
export default createField
|