Register a SA Forums Account here!
JOINING THE SA FORUMS WILL REMOVE THIS BIG AD, THE ANNOYING UNDERLINED ADS, AND STUPID INTERSTITIAL ADS!!!

You can: log in, read the tech support FAQ, or request your lost password. This dumb message (and those ads) will appear on every screen until you register! Get rid of this crap by registering your own SA Forums Account and joining roughly 150,000 Goons, for the one-time price of $9.95! We charge money because it costs us money per month for bills, and since we don't believe in showing ads to our users, we try to make the money back through forum registrations.
 
  • Post
  • Reply
Anony Mouse
Jan 30, 2005

A name means nothing on the battlefield. After a week, no one has a name.
Lipstick Apathy

Dancer posted:

Hi goons.

So, I'm a junior front end dev. I've had a total of 3 months of training, then managed to score a job right after, so feel free to explain things to me as if I'm stupid.

I am trying to get rid of a React warning, and I've managed to do it but I feel like my fix doesn't qualify as "good code", so I wanted to ask for advice.

The problem:

code:
  useEffect(() => {
    fetchGroups();
  }, []);
I get the react-hooks/exhaustive-deps warning.
If I add fetchGroups to the dependency array (and I add a silly console.log to the fetchGroups function) then I see that the function is triggered on every render, because although the function might be unchanged, its ref isn't.

This can be fixed with:

code:
  const fetchGroupsMemo = useCallback(fetchGroups, []);

  useEffect(() => {
    fetchGroupsMemo();
  }, []);
but I feel that this is a bad pattern, maybe? The compiler's inherent worry that "fetchGroups might change between renders" is not counteracted in any way by this. I just shift the dependency array from one hook to the other, and bypassing the array's function either way.

The in my mind best way to do this would be, because fetchGroups truly never changes, to move fetchGroups to a separate module and import it in (because that makes it non-mutable). Problem with this is I am using notistack to report whether the fetch has been successful, and notistack needs to be inside a component. This is also what's stopping me from moving the fetchGroups function inside the useEffect hook, because then I'd have to also add notistack's enqueueSnackbar as a dependency, and I feel like that would cause pure chaos in my app's memory, and would trigger who knows how many re-renders at weird times.
If you post more code it would help answer your question, because it really depends on the context of fetchGroups and whether it relies on state that changes between renders or if you're 1,000% sure that you only ever want it to run once only when the component first renders. It's also unclear how notistack plays into all of this.

Adbot
ADBOT LOVES YOU

Empress Brosephine
Mar 31, 2012

by Jeffrey of YOSPOS
I’m having a senior moment…what’s the best way to retrieve the value of a multi select with nodejs?

Lumpy
Apr 26, 2002

La! La! La! Laaaa!



College Slice

Empress Brosephine posted:

I’m having a senior moment…what’s the best way to retrieve the value of a multi select with nodejs?

isn't just an array of selected values keyed on the input name? And wouldn't it maybe be dependent on the web server you are running (i.e. "Node" doesn't know wtf a multiselect is)?

Empress Brosephine
Mar 31, 2012

by Jeffrey of YOSPOS
Yeah sorry wrote that in a rush; I’m using expressjs and was wondering how to access it with a req.body request. You are right though, it is a array!

Roadie
Jun 30, 2013

Empress Brosephine posted:

Yeah sorry wrote that in a rush; I’m using expressjs and was wondering how to access it with a req.body request. You are right though, it is a array!

You're still leaving out a lot here. Is it a application/x-www-form-urlencoded <form> POST, an SPA app that does JSON posts, what?

oh no computer
May 27, 2003

Edit: nevermind, I've found an alternative tutorial which walks me through installing Fomantic UI within a React app

Combat Pretzel
Jun 23, 2004

No, seriously... what kurds?!
What's the difference between {foo: 'bar'} and {'foo': 'bar'}? When I send former over the wire, e.g. via Express.js and then parse it on the other end, it turns out like latter. With latter x.foo doesn't work, tho. If I want former, I need to use a "reviver". However, when I specifically try to assign latter to a variable, it becomes the former anyhow.

Video Nasty
Jun 17, 2003

Combat Pretzel posted:

What's the difference between {foo: 'bar'} and {'foo': 'bar'}? When I send former over the wire, e.g. via Express.js and then parse it on the other end, it turns out like latter. With latter x.foo doesn't work, tho. If I want former, I need to use a "reviver". However, when I specifically try to assign latter to a variable, it becomes the former anyhow.

Stab in the dark, but
pre:
{foo: 'bar'}
is an object with a property. The latter is just two strings representing an object?

HappyHippo
Nov 19, 2003
Do you have an Air Miles Card?

Combat Pretzel posted:

What's the difference between {foo: 'bar'} and {'foo': 'bar'}? When I send former over the wire, e.g. via Express.js and then parse it on the other end, it turns out like latter. With latter x.foo doesn't work, tho. If I want former, I need to use a "reviver". However, when I specifically try to assign latter to a variable, it becomes the former anyhow.

There shouldn't be a difference. What do you mean by "With latter x.foo doesn't work"?

code:
var x = {'foo': 'bar'};
var y = {foo: 'bar'};

alert(x.foo);
alert(y.foo);
Works fine for me.

Doom Mathematic
Sep 2, 2008

Combat Pretzel posted:

What's the difference between {foo: 'bar'} and {'foo': 'bar'}? When I send former over the wire, e.g. via Express.js and then parse it on the other end, it turns out like latter. With latter x.foo doesn't work, tho. If I want former, I need to use a "reviver". However, when I specifically try to assign latter to a variable, it becomes the former anyhow.

In JavaScript source code,

JavaScript code:
const x = {'foo': 'bar'}
and

JavaScript code:
const x = {foo: 'bar'}
do precisely the same thing. In this context, the single quotes around the property name 'foo' are unnecessary and can be omitted without changing the meaning of the code. It's not possible to distinguish between the two values of x. x.foo evaluates to the string 'bar' in both cases.

As for "sending over the wire", that's not JavaScript code anymore. You're probably sending JSON, which is not the same thing at all as JavaScript code. Probably what's happening is that somewhere in your client the JavaScript value is getting stringified out as a JSON string:

JavaScript code:
const x = {foo: 'bar'}
const str = JSON.stringify(x)
Here str is the 13-character string '{"foo":"bar"}'. In both cases. So there's probably something else going on here.

Roadie
Jun 30, 2013

Combat Pretzel posted:

What's the difference between {foo: 'bar'} and {'foo': 'bar'}? When I send former over the wire, e.g. via Express.js and then parse it on the other end, it turns out like latter. With latter x.foo doesn't work, tho. If I want former, I need to use a "reviver". However, when I specifically try to assign latter to a variable, it becomes the former anyhow.

It sounds like you don't understand JSON. You're not sending JS objects directly in requests/responses, you're sending a stringified representation with certain formatting requirements that has to be parsed (some frameworks will do this implicitly for convenience reasons) to get the object back.

Combat Pretzel posted:

With latter x.foo doesn't work, tho.

You're probably trying to do something to a JSON string representation '{"foo": "bar"}', not an object {foo: "bar"}. You need to JSON.parse it to get the object.

Combat Pretzel posted:

However, when I specifically try to assign latter to a variable

JavaScript code:
// var1 and var2 are identical objects
const var1 = {"foo": "bar"}
const var2 = {foo: "bar"}

// var3, var4, and var5 are identical strings (but note the lack of space after the colon, to match JSON.stringify output)
const var3 = '{"foo":"bar"}'
const var4 = JSON.stringify({"foo": "bar"})
const var5 = JSON.stringify({foo: "bar"})
You're probably confusing these two different things.

Roadie fucked around with this message at 20:05 on Mar 25, 2021

roomforthetuna
Mar 22, 2005

I don't need to know anything about virii! My CUSTOM PROGRAM keeps me protected! It's not like they'll try to come in through the Internet or something!
One other difference between {foo: 'bar'} and {'foo': 'bar'} is that some Javascript compiler/minifier/obfuscator tools will mangle the former but will not mangle the latter, with the assumption that e.g. replacing 'foo' with 'q' throughout the code will work fine if you've 100% used it object-style, but when you've declared it as explicitly string-keys the compiler will treat it as intentionally string-keys with the assumption that you intended to be able to serialize it or use it to look up things from other containers or the like.

MrMoo
Sep 14, 2000

The former is valid JavaScript-only and latter is valid JSON and JavaScript. Use the first in coding, the latter in messaging, the latter if you need a space in a field name.

MrMoo fucked around with this message at 17:04 on Mar 26, 2021

Doom Mathematic
Sep 2, 2008
The 14-character string "{'foo': 'bar'}" is not valid JSON. JSON requires double quotes around both the key and the value: '{"foo": "bar"}'. But having said that: nobody should be hand-writing JSON messages. I suggest using JSON.stringify({foo: 'bar'}) and letting the serializer handle that.

MrMoo
Sep 14, 2000

Doom Mathematic posted:

I suggest using JSON.stringify({foo: 'bar'}) and letting the serializer handle that.

The correct answer, as you can also play like this:
JavaScript code:
const foo = ‘bar’;
JSON.stringify({ foo });

Empress Brosephine
Mar 31, 2012

by Jeffrey of YOSPOS
e; nevermind I figured it out

Empress Brosephine fucked around with this message at 16:30 on Mar 30, 2021

TengenNewsEditor
Apr 3, 2004

It seems like if a React application is even a tiny bit complex, the parent components are going to need to know what's going on in the child components. React doesn't support accessing anything in child components (without refs, which seems hacky), and the recommended solution, "lifting up state," is bizarre. Pushing up everything to the top level removes a lot of the benefits of using a framework like React in the first place. Oh yeah, and React doesn't support a nested state, so you're forced to flatten your data and at that point you might as well be using a relational database backed framework like django.

Am I looking at this all wrong?

TengenNewsEditor fucked around with this message at 14:30 on Apr 5, 2021

Bruegels Fuckbooks
Sep 14, 2004

Now, listen - I know the two of you are very different from each other in a lot of ways, but you have to understand that as far as Grandpa's concerned, you're both pieces of shit! Yeah. I can prove it mathematically.

TengenNewsEditor posted:

It seems like if a React application is even a tiny bit complex, the parent components are going to need to know what's going on in the child components. React doesn't support accessing anything in child components (without refs, which seems hacky), and the recommended solution, "lifting up state," is bizarre. Pushing up everything to the top level removes a lot of the benefits of using a framework like React in the first place. Oh yeah, and React doesn't support a nested state, so you're forced to flatten your data and at that point you might as well be using a relational database backed framework like django.

Am I looking at this all wrong?

What's wrong with using a callback for child to parent communication?

roomforthetuna
Mar 22, 2005

I don't need to know anything about virii! My CUSTOM PROGRAM keeps me protected! It's not like they'll try to come in through the Internet or something!

TengenNewsEditor posted:

Am I looking at this all wrong?
You're feeling angry about how stupid it is, and thinking almost anything else would be better, so I'd say you're looking at it just right.

TengenNewsEditor
Apr 3, 2004

Bruegels Fuckbooks posted:

What's wrong with using a callback for child to parent communication?

That works great if you only need to process the child's state when it changes, but you would still need to cache the result of the callback in the parent if you need to do processing based on the child state later.

Combat Pretzel
Jun 23, 2004

No, seriously... what kurds?!
Pass an object reference of the child (this) up to the parent somehow, then go hogwild.

xtal
Jan 9, 2011

by Fluffdaddy

Combat Pretzel posted:

Pass an object reference of the child (this) up to the parent somehow, then go hogwild.

I sure hope this is a joke...

fsif
Jul 18, 2003

TengenNewsEditor posted:

Am I looking at this all wrong?

Yeah I think so. Django and React aren't really that comparable of frameworks/libraries and they set out to solve different problems. My sense is that if you'd prefer to work on the view layer in Python, you're probably not the type of developer that React would appeal to.

The issue with props drilling/lifting up state is a commonly identified pain point. If a React app has some appreciable level of complexity, developers usually install a state management library like Redux or zustand.

smackfu
Jun 7, 2004

Yeah, this isn’t exactly a hot take, redux has been around for five years.

It even got to the point where everyone was using redux everywhere and it was taught in beginner tutorials so the redux site now has a page on why you should not use it.

I think React context is a decent alternative now?

TengenNewsEditor
Apr 3, 2004

Combat Pretzel posted:

Pass an object reference of the child (this) up to the parent somehow, then go hogwild.

xtal posted:

I sure hope this is a joke...

Honestly this is the most attractive suggestion I've seen so far (aside from 'don't use react) - and that fact that it is not "react-like" sours me on react even more.

fsif posted:

Yeah I think so. Django and React aren't really that comparable of frameworks/libraries and they set out to solve different problems. My sense is that if you'd prefer to work on the view layer in Python, you're probably not the type of developer that React would appeal to.

The issue with props drilling/lifting up state is a commonly identified pain point. If a React app has some appreciable level of complexity, developers usually install a state management library like Redux or zustand.

I don't want to use django since this app shouldn't require an ORM. My point is if I need to use a state manager or normalize/flatten my state application wide, am I even getting any benefit from using React over a heavy ORM framework anymore?

gbut
Mar 28, 2008

😤I put the UN🇺🇳 in 🎊FUN🎉


TengenNewsEditor posted:

It seems like if a React application is even a tiny bit complex, the parent components are going to need to know what's going on in the child components. React doesn't support accessing anything in child components (without refs, which seems hacky), and the recommended solution, "lifting up state," is bizarre. Pushing up everything to the top level removes a lot of the benefits of using a framework like React in the first place. Oh yeah, and React doesn't support a nested state, so you're forced to flatten your data and at that point you might as well be using a relational database backed framework like django.

Am I looking at this all wrong?

I'm about to experiment with Recoil, as it seems to solve the shortcomings of Redux state management for any moderate+ complexity.

gbut
Mar 28, 2008

😤I put the UN🇺🇳 in 🎊FUN🎉


smackfu posted:

Yeah, this isn’t exactly a hot take, redux has been around for five years.

It even got to the point where everyone was using redux everywhere and it was taught in beginner tutorials so the redux site now has a page on why you should not use it.

I think React context is a decent alternative now?

Context can't be dynamic, thus my above take. The recoil.js intro video explains a bunch of benefits of its approach, and seems to solve dynamic shared state pretty elegantly.

fsif
Jul 18, 2003

TengenNewsEditor posted:

I don't want to use django since this app shouldn't require an ORM. My point is if I need to use a state manager or normalize/flatten my state application wide, am I even getting any benefit from using React over a heavy ORM framework anymore?

I assume so? You're getting all of the normal benefits of React and something like zustand or the aforementioned native Context API take about thirty minutes to learn and are much lighter weight than an ORM framework. They will give you a global state object, which is what I think you're looking for.

TengenNewsEditor
Apr 3, 2004

A global state manager shouldn't be necessary to get properties from a child component. It's insane that composition is fundamentally broken and the answer is 'use a global state manager'.

(Recoil does look like a pretty good state manager though)

Lumpy
Apr 26, 2002

La! La! La! Laaaa!



College Slice

TengenNewsEditor posted:

It seems like if a React application is even a tiny bit complex, the parent components are going to need to know what's going on in the child components. React doesn't support accessing anything in child components (without refs, which seems hacky), and the recommended solution, "lifting up state," is bizarre. Pushing up everything to the top level removes a lot of the benefits of using a framework like React in the first place. Oh yeah, and React doesn't support a nested state, so you're forced to flatten your data and at that point you might as well be using a relational database backed framework like django.

Am I looking at this all wrong?

You are probably looking at it all wrong. I have written many complex React apps, and "parent components needing to know what is going on in the child components" is not a thing that comes up much, if ever.

Can you give an example of the issues you are facing?

Ima Computer
Oct 28, 2007

Stop all the downloading!

Help computer.
React is entirely built around the idea of unidirectional top-down data flow. Accessing a child component's properties is a big anti-pattern and red flag. If you find yourself wanting to communicate back up the component tree, in most cases, pulling state up is the most appropriate solution. For the rare instances when you really need to communicate child state updates back up the tree, escape hatches exist: passing callback functions as props, using context, or bringing in a state management library like redux (yuck, don't do this). I'm getting big XY problem vibes here though.

Ima Computer fucked around with this message at 17:29 on Apr 5, 2021

Roadie
Jun 30, 2013

fireraiser posted:

React is entirely built around the idea of unidirectional top-down data flow. Accessing a child component's properties is a big anti-pattern and red flag. If you find yourself wanting to communicate back up the component tree, in most cases, pulling state up is the most appropriate solution. For the rare instances when you really need to communicate child state updates back up the tree, escape hatches exist: passing callback functions as props, using context, or bringing in a state management library like redux (yuck, don't do this). I'm getting big XY problem vibes here though.

Same. What are you actually trying to do here, TengenNewsEditor?

TengenNewsEditor
Apr 3, 2004

Let me ask this - where is business logic supposed to go in a client-side only react app? Assuming you're avoiding a state management library.

Putting it child components requires communicating the results up the tree. For example if an account profile totals itself, the parent customer profile will need to get the totals from all the accounts to create an overall total.
If you put it all in a top level component you end up with a god component.
React seems like it ought to work best as a View only framework - that suggests the business logic ought to be elsewhere, let's say in vanilla javascript, and then sending the data top-down through all the components. That seems fine, but there isn't much documentation or conversation on this workflow and it seems pretty difficult to send changes to react from 'outside'.

TengenNewsEditor fucked around with this message at 18:09 on Apr 5, 2021

TengenNewsEditor
Apr 3, 2004

Roadie posted:

Same. What are you actually trying to do here, TengenNewsEditor?

Honestly I just want to understand how unidirectional top-down flow is intended to work for an application with client-side business logic. Nearly all the examples I've seen sidestep the issue by using a global state manager.

fsif
Jul 18, 2003

TengenNewsEditor posted:

React seems like it ought to work best as a View only framework

That's—out of the box—all React has purported to be. It's narrow in scope and extendable by design. If you don't like cobbling together third party libraries for things like state management, routing, or server side rendering, you can either choose a more fleshed out React starter pack like Next.js, or choose a different, more opinionated JavaScript framework like Vue.

Roadie
Jun 30, 2013

TengenNewsEditor posted:

For example if an account profile totals itself, the parent customer profile will need to get the totals from all the accounts to create an overall total.

This is a fundamentally bad thing to do in React because you're going to be re-rendering everything a whole bunch of times as all your updaters fire off. Do it declaratively, not imperatively: define your totals as a derived value of your incoming data, with memoized wrappers if necessary to reduce total recalculation.

TengenNewsEditor posted:

Honestly I just want to understand how unidirectional top-down flow is intended to work for an application with client-side business logic. Nearly all the examples I've seen sidestep the issue by using a global state manager.

TengenNewsEditor posted:

React seems like it ought to work best as a View only framework - that suggests the business logic ought to be elsewhere, let's say in vanilla javascript, and then sending the data top-down through all the components. That seems fine, but there isn't much documentation or conversation on this workflow and it seems pretty difficult to send changes to react from 'outside'.

For this kind of setup, the global state manager is where you put your client-side business logic. The reason Redux is so popular for this is that it plays nice with React's top-down-data-flow concept while allowing arbitrarily complex custom extensions once you add in middleware.

TengenNewsEditor
Apr 3, 2004

Thanks, if you look at react as a 'view-only' framework, top-down unidirectional makes a lot more sense.

But if it's a view-only library why is it such a pain in the rear end to get external data into it? And if you're supposed to populate the top level component with a model of your entire application, how do you manage page re-renders for a nested state? Do you need a global state manager if you're not able to flatten out your application's model?

Roadie
Jun 30, 2013

TengenNewsEditor posted:

Thanks, if you look at react as a 'view-only' framework, top-down unidirectional makes a lot more sense.

But if it's a view-only library why is it such a pain in the rear end to get external data into it?
It's not, though?

TengenNewsEditor posted:

And if you're supposed to populate the top level component with a model of your entire application, how do you manage page re-renders for a nested state? Do you need a global state manager if you're not able to flatten out your application's model?
I'm unclear on what you're trying to ask here.

TengenNewsEditor
Apr 3, 2004

Roadie posted:

It's not, though?

Actually really helpful. One of the tests I had tried was a vanilla JS app that sent output to a top level react Component. It hadn't worked before but your comment spurred me to go back to it and find the problem.

The other part was asking how to deal with react only updating when the top level state object changes, and failing to update if a member of the state object changes. But that's an understandable limitation & I know some of the common workarounds.

Adbot
ADBOT LOVES YOU

Roadie
Jun 30, 2013

TengenNewsEditor posted:

The other part was asking how to deal with react only updating when the top level state object changes, and failing to update if a member of the state object changes. But that's an understandable limitation & I know some of the common workarounds.

React uses shallow equality for props/state update comparisons. If you want it to re-render, give it a new object (and new objects for any updated properties), not a mutated object.

This is part of why so many examples out there default to spread syntax for setState or reducer syntax.

Roadie fucked around with this message at 23:41 on Apr 5, 2021

  • 1
  • 2
  • 3
  • 4
  • 5
  • Post
  • Reply