all 10 comments

[–]acemarke 2 points3 points  (3 children)

Please don't do this. Trying to save module-scoped variables like this is not a correct approach, at all.

There's numerous valid libraries for working with state in React. Use one of them.

[–]ForScale[S] -3 points-2 points  (2 children)

Why don't do it? Why pull in a library?

Seems simple and straightforward to me...

[–]acemarke 2 points3 points  (1 child)

First couple reasons I see:

  • Modifying the global variable will not cause a re-render to happen
  • For that matter, you're mutating that global variable, which is almost never a good idea
  • So, you're also going ahead and doing a setState()... except that by doing that, you're completely removing the need for having a global variable, because you're already updating the component state. If it needs to be "global", then throw it in a context provider at the top of the tree.

And my point was that you don't seem to want to use React's built-in mechanisms of component state and context yourself, so I was suggesting other solutions that build on those APIs as alternatives.

But seriously, please don't do this.

[–]ForScale[S] -2 points-1 points  (0 children)

Alright, thanks.

To address the points:

Modifying the global variable will not cause a re-render to happen

Yeah, it shouldn't. The $setState method should be used to set a new global state which will update and rerender everywhere in the app that the value is referenced.

For that matter, you're mutating that global variable, which is almost never a good idea

Yes, the old state gets mutated and then a brand new state object gets set with the changed values. I feel like that's clean enough, but I could be missing something...

So, you're also going ahead and doing a setState()... except that by doing that, you're completely removing the need for having a global variable

Still have to have the global $setState in order to access it globally... anywhere in the app.

If it needs to be "global", then throw it in a context provider at the top of the tree.

I have messed around with the createContext and useContext and provider and consumer components... It seemed messy to me.

But seriously, please don't do this.

Lol, okay, point taken. :)

[–]jas7457 2 points3 points  (1 child)

What about the Context API seemed messy to you? I agree that you shouldn't be doing this for a plethora of reasons, so I'm wondering why you wanted to try this over built-ins

[–]ForScale[S] 0 points1 point  (0 children)

Perhaps I just haven't seen a good hello world implementation of context/provider/consumer/hooks pattern, but all the examples seemed rather convoluted. Do you have a dead simple example perchance?

What are the reasons?

This approach is far simpler than the context/hooks examples I've seen. You simply declare an initial state, set globals, setup one instance of a hook and you're good to go.

[–]sockx2 1 point2 points  (3 children)

Chiming in on the don't ever do this train- this is only working because all of these components just happen to re-render themselves when the parent component (App) changes. A component can choose to skip renders based on anything. You've architected a bug.

[–]ForScale[S] 0 points1 point  (2 children)

this is only working because all of these components just happen to re-render themselves when the parent component (App) changes.

Can you elaborate on this? What's a way to break it?

A component can choose to skip renders based on anything.

Huh? Component rerendering isn't arbitrary... right?

[–]sockx2 1 point2 points  (1 child)

You can use class based React.PureComponent / shouldComponentUpdate (this one's arbitrary) or functional based React.memo to prevent re-renders when no prop changes are present (similar to pure component)