Skip to content

Instantly share code, notes, and snippets.

@reaktivo
Last active July 20, 2018 14:20
Show Gist options
  • Save reaktivo/5b19f1a6e84260653d791dea1c8ecd2d to your computer and use it in GitHub Desktop.
Save reaktivo/5b19f1a6e84260653d791dea1c8ecd2d to your computer and use it in GitHub Desktop.
Stateful functional component sketch
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>
);
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