Last active
July 20, 2018 14:20
-
-
Save reaktivo/5b19f1a6e84260653d791dea1c8ecd2d to your computer and use it in GitHub Desktop.
Stateful functional component sketch
This file contains hidden or 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
import React, { PureComponent } from "react"; | |
import ReactDOM from "react-dom"; | |
import "./styles.css"; | |
const withState = render => | |
class extends PureComponent { | |
state = { value: "xxx" }; | |
onChange = event => this.setState({ value: event.target.value }); | |
render = () => render(this); | |
}; | |
const Form = ({ state, onChange }) => ( | |
<div className="App"> | |
<h1>{state.value}</h1> | |
<input value={state.value} onChange={onChange} /> | |
</div> | |
); | |
const FormWithState = withState(Form); | |
const App = () => ( | |
<React.Fragment> | |
<FormWithState /> | |
</React.Fragment> | |
); |
This file contains hidden or 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
import React from "react"; | |
import ReactDOM from "react-dom"; | |
import "./styles.css"; | |
function mapObject(obj, fn) { | |
return Object.keys(obj || {}).reduce((acc, key) => { | |
acc[key] = fn(obj[key], key); | |
return acc; | |
}, {}); | |
} | |
function withDefaultProps(defaultProps) { | |
return Component => props => <Component {...defaultProps} {...props} />; | |
} | |
function result(target) { | |
return typeof target === "function" ? target() : target; | |
} | |
class State extends React.PureComponent { | |
static create = props => withDefaultProps(props)(State); | |
static defaultProps = { | |
initialState: {}, | |
handlers: {}, | |
transform: identity => identity | |
}; | |
state = result(this.props.initialState); | |
setState = this.setState.bind(this); | |
handlers = mapObject(this.props.handlers, fn => fn(this)); | |
render() { | |
const { children, transform } = this.props; | |
return children(transform(this)); | |
} | |
} | |
const createFn = defaultProps => children => ( | |
<State {...defaultProps}>{children}</State> | |
); | |
const state = createFn({ | |
initialState: { | |
value: "xxx" | |
}, | |
fetch: (...args) => console.log(...args), | |
handlers: { | |
onChange: ({ setState }) => ({ target }) => { | |
setState({ value: target.value }); | |
}, | |
onSubmit: ({ props }) => (...args) => { | |
props.fetch("onsubmit"); | |
} | |
}, | |
transform: ({ handlers, state }) => ({ | |
onChange: handlers.onChange, | |
onSubmit: handlers.onSubmit, | |
value: state.value | |
}) | |
}); | |
const Form = () => | |
state(({ value, onChange, onSubmit }) => ( | |
<div className="App"> | |
<h1>{value}</h1> | |
<h2>Start editing to see some magic happen!</h2> | |
<input value={value} onChange={onChange} /> | |
<input type="submit" onClick={onSubmit} /> | |
</div> | |
)); | |
const App = () => ( | |
<React.Fragment> | |
<Form /> | |
<Form /> | |
</React.Fragment> | |
); | |
const rootElement = document.getElementById("root"); | |
ReactDOM.render(<App />, rootElement); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment