Skip to content

Instantly share code, notes, and snippets.

@trueadm
Last active July 14, 2020 06:41
Show Gist options
  • Save trueadm/198ae6902d2c5459e91a8e571b561b40 to your computer and use it in GitHub Desktop.
Save trueadm/198ae6902d2c5459e91a8e571b561b40 to your computer and use it in GitHub Desktop.
// Option C:
// this implementation has a small amount of overhead compared to (a) and (b)
const React = require('react');
const counterState = React.createStateReducer({
initialState: props => ({
counter: 0,
divRef: React.createRef(),
}),
reducer: (action, state) => {
switch (action) {
case "INCREMENT": {
return React.updateState({counter: state.counter + 1});
}
}
},
didUpdate: (props, state) => {
state.divRef.style.color = props.color;
},
});
function CounterComponent(props) {
return counterState(props, (state, reduce) =>
<div ref={state.divRef} onClick={() => reduce("INCREMENT"))}>
Count: {state.counter}
</div>
);
}
module.exports = CounterComponent;
// Option D:
// has the least overhead of all the implementations in Safari
const React = require('react');
function initialState(props) (
return {
counter: 0,
divRef: React.createRef(),
}
)
function reducer(action, state) (
switch (action) {
case "INCREMENT": {
return React.updateState({counter: state.counter + 1});
}
}
)
function didUpdate(props, state) {
state.divRef.style.color = props.color;
}
function CounterComponent(props) {
return React.createStateReducer(
{props, initialState, reducer, didUpdate},
(state, reduce) => (
<div ref={state.divRef} onClick={() => reduce("INCREMENT"))}>
Count: {state.counter}
</div>
)
);
}
module.exports = CounterComponent;
// Option E:
// has the least overhead of all the implementations in Chrome/Node/Firefox
const React = require('react');
const CounterComponent = {
initialState(props) {
return {
counter: 0,
divRef: React.createRef(),
}
},
reducer(action, state) (
switch (action) {
case "INCREMENT": {
return React.updateState({counter: state.counter + 1});
}
},
didUpdate(props, state) {
state.divRef.style.color = props.color;
},
render(props, state, reduce) {
return (
<div ref={state.divRef} onClick={() => reduce("INCREMENT"))}>
Count: {state.counter}
</div>
);
}
}
module.exports = CounterComponent;
// Option A:
// this implementation has quite a bit of overhead in all browsers due to the
// function creation in the functional component
const React = require('react');
const counterState = React.createState();
const counterReducer = (action, state) => {
switch (action) {
case "INCREMENT": {
return React.updateState({counter: state.counter + 1});
}
}
};
function CounterComponent(props) {
return counterState({
initialState: () => ({
counter: 0,
divRef: React.createRef(),
}),
didUpdate: state => {
state.divRef.style.color = props.color;
},
reducer: counterReducer,
render(state, reduce) {
return (
<div ref={state.divRef} onClick={() => reduce("INCREMENT"))}>
Count: {state.counter}
</div>
);
}
});
}
module.exports = CounterComponent;
// Option B:
// this implementation has quite a bit of overhead in all browsers due to the
// function creation in the functional component
const React = require('react');
const counterState = React.createStateReducer((action, state) => {
switch (action) {
case "INCREMENT": {
return React.updateState({counter: state.counter + 1});
}
}
});
function CounterComponent(props) {
return counterState({
initialState: () => ({
counter: 0,
divRef: React.createRef(),
}),
didUpdate: state => {
state.divRef.style.color = props.color;
},
render(state, reduce) {
return (
<div ref={state.divRef} onClick={() => reduce("INCREMENT"))}>
Count: {state.counter}
</div>
);
}
});
}
module.exports = CounterComponent;
@trueadm
Copy link
Author

trueadm commented Nov 13, 2017

@bvaughn I've updated example E after speaking with Dan. I think example A and B are probably going to be no goes because of the overhead they add in the render phase. The naming of createState() was also probably not the right name for this method.

The reason I went with different lifecycle names was purely to avoid confusion with existing ones – as the arguments passed wouldn't match up. I'm not fussed on name, I just didn't want to create more confusion. We could also infer async by default with some of them, to help the async story more (rather than sync like they are now).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment