Create a gist now

Instantly share code, notes, and snippets.

What would you like to do?
// 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;
@MatejMazur

This comment has been minimized.

Show comment Hide comment
@MatejMazur

MatejMazur Nov 11, 2017

Maybe a small mistake but line 8 at example-a.js and line 7 at example-b.js:

return React.updateState({...state, {counter: state.counter + 1}});

or where do you get that counter?

MatejMazur commented Nov 11, 2017

Maybe a small mistake but line 8 at example-a.js and line 7 at example-b.js:

return React.updateState({...state, {counter: state.counter + 1}});

or where do you get that counter?

@trueadm

This comment has been minimized.

Show comment Hide comment
@trueadm

trueadm Nov 11, 2017

@MatejMazur well spotted!

Owner

trueadm commented Nov 11, 2017

@MatejMazur well spotted!

@tizmagik

This comment has been minimized.

Show comment Hide comment
@tizmagik

tizmagik Nov 12, 2017

Interesting! Wondering, do you need the return React.updateState({...})? Would you ever return anything else?

Interesting! Wondering, do you need the return React.updateState({...})? Would you ever return anything else?

@trueadm

This comment has been minimized.

Show comment Hide comment
@trueadm

trueadm Nov 12, 2017

@tizmagik, there might be different types of update, like async updates etc. It opens up more routes in the future.

Owner

trueadm commented Nov 12, 2017

@tizmagik, there might be different types of update, like async updates etc. It opens up more routes in the future.

@bvaughn

This comment has been minimized.

Show comment Hide comment
@bvaughn

bvaughn Nov 13, 2017

Disclaimer: I'm super jet-lagged and my brain is only half working at the moment, but since Dom asked me to take a look- I think I like option-e the best. 😄

I do have a thought or two:

  • example-a: I'm curious why React.createState returns a function instead of a state? Doesn't seem obvious why that's necessary since it doesn't accept any arguments. Is it just to make it more comparable to the others?
  • example-e: Does the CounterComponent function even need to exist? All it does is relay props. Could reduce boilerplate a little with just:
modules.exports = React.createReducerComponent(counterComponent);

I'd also like to learn a little more about the constraints of didUpdate. What types of things- other than tweaking refs- is it okay to do in this lifecycle? (Is there anything that's safe to do in eg componentDidMount that it won't be safe to do in didUpdate without causing deopts?)

bvaughn commented Nov 13, 2017

Disclaimer: I'm super jet-lagged and my brain is only half working at the moment, but since Dom asked me to take a look- I think I like option-e the best. 😄

I do have a thought or two:

  • example-a: I'm curious why React.createState returns a function instead of a state? Doesn't seem obvious why that's necessary since it doesn't accept any arguments. Is it just to make it more comparable to the others?
  • example-e: Does the CounterComponent function even need to exist? All it does is relay props. Could reduce boilerplate a little with just:
modules.exports = React.createReducerComponent(counterComponent);

I'd also like to learn a little more about the constraints of didUpdate. What types of things- other than tweaking refs- is it okay to do in this lifecycle? (Is there anything that's safe to do in eg componentDidMount that it won't be safe to do in didUpdate without causing deopts?)

@trueadm

This comment has been minimized.

Show comment Hide comment
@trueadm

trueadm 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).

Owner

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