Skip to content

Instantly share code, notes, and snippets.

@mehiel
Last active December 22, 2016 03:42
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mehiel/cd8bd5be02349b3c7c2e8cec627854a2 to your computer and use it in GitHub Desktop.
Save mehiel/cd8bd5be02349b3c7c2e8cec627854a2 to your computer and use it in GitHub Desktop.
A proof-of-concept stateless form in react
import ReactDOM from 'react-dom'
import { PropTypes } from 'react'
import map from 'ramda/src/map'
import toPairs from 'ramda/src/toPairs'
import compose from 'ramda/src/compose'
import propOr from 'ramda/src/propOr'
import curry from 'ramda/src/curry'
const { string, object, func } = PropTypes
const _onChange = (action, values) => (ev) => {
const field = ev.target.name
const value = ev.target.value
const change = { [field]: value }
action({ ...values, ...change }, change, ev)
}
const _onSubmit = (action, values) => (ev) => {
action(values, ev)
}
// formSchema is of shape: [ ['fieldName', fieldSchema, value, error], ... ]
const formSchema = (schema, values, errors) =>
compose(map(([key, schema]) => [key, schema, propOr(undefined, key, values), propOr(undefined, key, errors)]), toPairs)(schema)
const schemaToField = curry((onChange, [name, fieldSchema, value, error]) => (
<div key={name}>
<input type={propOr('text', 'type', fieldSchema)}
name={name} placeholder={fieldSchema.label}
value={value} onChange={onChange} />
<span>{error}</span>
</div>
))
const renderFields = (onChange) => map(schemaToField(onChange))
const Form = ({ className, schema, values, errors, onSubmit, onChange }) => (
<form onSubmit={_onSubmit(onSubmit, values)}>
{renderFields(_onChange(onChange, values))(formSchema(schema, values, errors))}
<button type='submit' style={{ display: 'none' }} />
</form>
)
Form.propTypes = {
className: string,
schema: object,
values: object,
errors: object,
onSubmit: func,
onChange: func,
}
const schema = {
username: { label: 'Username' },
password: { label: 'Password', type: 'password' },
}
ReactDOM.render(
<Form schema={schema} values={...} errors={...}
onChange={...} onSubmit={...} />,
document.getElementById("root")
)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment