Created
August 17, 2017 19:21
-
-
Save ryanflorence/947cbcca1d28fe17adbda9689d4fcac6 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/*eslint-disable no-alert */ | |
import React from "react" | |
import ReactDOM from "react-dom" | |
import PropTypes from "prop-types" | |
class Form extends React.Component { | |
static childContextTypes = { | |
form: PropTypes.shape({ | |
submit: PropTypes.func.isRequired, | |
inputChange: PropTypes.func.isRequired, | |
reset: PropTypes.func.isRequired, | |
values: PropTypes.object.isRequired | |
}).isRequired | |
} | |
state = { | |
values: {} | |
} | |
getChildContext() { | |
return { | |
form: { | |
values: this.state.values, | |
reset: () => this.setState({ values: {} }), | |
submit: () => this.props.onSubmit(this.state.values), | |
inputChange: (key, value) => { | |
this.setState({ | |
values: { | |
...this.state.values, | |
[key]: value | |
} | |
}) | |
} | |
} | |
} | |
} | |
render() { | |
return ( | |
<div> | |
{this.props.children} | |
</div> | |
) | |
} | |
} | |
class ResetButton extends React.Component { | |
static contextTypes = { | |
form: PropTypes.shape({ | |
reset: PropTypes.func.isRequired | |
}).isRequired | |
} | |
handleClick = () => { | |
this.context.form.reset() | |
} | |
render() { | |
return ( | |
<button onClick={this.handleClick}> | |
{this.props.children} | |
</button> | |
) | |
} | |
} | |
class SubmitButton extends React.Component { | |
static contextTypes = { | |
form: PropTypes.shape({ | |
submit: PropTypes.func.isRequired | |
}).isRequired | |
} | |
handleClick = () => { | |
this.context.form.submit() | |
} | |
render() { | |
return ( | |
<button onClick={this.handleClick}> | |
{this.props.children} | |
</button> | |
) | |
} | |
} | |
class TextInput extends React.Component { | |
static contextTypes = { | |
form: PropTypes.shape({ | |
submit: PropTypes.func.isRequired, | |
inputChange: PropTypes.func.isRequired, | |
values: PropTypes.object.isRequired | |
}).isRequired | |
} | |
render() { | |
return ( | |
<input | |
type="text" | |
name={this.props.name} | |
value={this.context.form.values[this.props.name] || ""} | |
placeholder={this.props.placeholder} | |
onChange={event => { | |
this.context.form.inputChange(this.props.name, event.target.value) | |
}} | |
onKeyDown={event => { | |
if (event.key === "Enter") { | |
this.context.form.submit() | |
} | |
}} | |
/> | |
) | |
} | |
} | |
class App extends React.Component { | |
handleSubmit = values => { | |
console.log(values) | |
} | |
render() { | |
return ( | |
<div> | |
<h1> | |
This isn't even my final <code><Form/></code>! | |
</h1> | |
<Form onSubmit={this.handleSubmit}> | |
<p> | |
<TextInput name="firstName" placeholder="First Name" /> {" "} | |
<TextInput name="lastName" placeholder="Last Name" /> | |
</p> | |
<p> | |
<SubmitButton>Submit</SubmitButton> | |
<ResetButton>Reset</ResetButton> | |
</p> | |
</Form> | |
</div> | |
) | |
} | |
} | |
ReactDOM.render(<App />, document.getElementById("app")) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment