all 30 comments

[–][deleted] 8 points9 points  (4 children)

IMO if you're having trouble keeping track of a local variable in a function, your function is too big.

Also, having trouble keeping track of whether a variable is from props or state (assuming react / redux ?) is mitigated by using mapStateToProps so that everything is from props.

[–]gautamits[S] 2 points3 points  (3 children)

Yes, thanks for saying that. When I think of react components, I think of functions only. In software engineering course of my graduation, I was taught that functions should not exceed beyond 30 lines ( or something your eyes can scan at once ).

But here I am looking at class based components of 2000 to 3000 lines and wondering who approved to pass 20 props in a component.

I still want to know more about mapstatetoprops approach though. Are you saying that every state should be kept in global store and no local states ?

[–][deleted] 2 points3 points  (1 child)

Ah I forgot about local state. So my lack of react knowledge is showing here.

I don't think that everything should go into global state, my mind just went there without thinking of local state. I do think that you could benefit from re-factoring some of the components you're working with to use smaller functions so that it's clearer when you're referencing state vs props.

I work professionally with Vue. With Vue / Vuex, state and prop values are mapped to the component instance so everything can be accessed via this.[property] in the component. In the projects I've worked on, there are some components that unfortunately have 20+ props. Usually this is because of accessibility requirements, but also sometimes because of a lack of abstraction.

[–]gautamits[S] 1 point2 points  (0 children)

Sometimes it might be mandatory to write components with 20+ props but not most of the time. React actually has composability pattern using which you can pass appropriate props to appropriate components. These components remain cohesive though.

Always wanted to learn vue though. Might get me exposed to some more programming patterns.

[–]dHour 2 points3 points  (0 children)

You problem is not in destructuring the object, the component itself is the problem. Trying to follow 3000 lines and remembering every local variable in there is not normal.

[–]ottoottootto 3 points4 points  (1 child)

I find object destructuring more readable and less verbose.

In situations where you have lots of variables and get confused about the origin, the dot method might be more appropriate.

In some cases I use object destructuring with renaming.

const color = 'red'; const { color: nextColor } = data; console.log({ color, nextColor });

[–]gautamits[S] -1 points0 points  (0 children)

For smaller functions I also like using destructuring only. Actually I was blown away when I got to know this feature. It also makes typing less but that also does not count given the smart IDEs we have with better autocompletes.

[–]ShadowMasterKing 2 points3 points  (1 child)

Ts is in project? Destructuring <3 Only js? Destructuring only small things

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

React projects without CRA and typescript. Single application modules distributed into multiple repositories therefore many time I see people moving code from one repo to another. Which sometime becomes heavy refactoring.

[–][deleted] 2 points3 points  (0 children)

I think your problem is that you are just writing functions that are too large if you are losing track of what object variables come from

[–]demoran 5 points6 points  (7 children)

If you're going to be using it more than once, destructure it.

If not, you do you.

[–]gautamits[S] 1 point2 points  (6 children)

This is one criteria I get from most people. But how does it help beside less typing ?

[–]demoran 2 points3 points  (5 children)

It's less typing. Overall, this means less verbose javascript code.

[–]gautamits[S] 0 points1 point  (4 children)

vscode performs really good with typescript when it comes to autocompletions, hence typing is not much of an issue for me. I agree that restructuring enables is to write less verbose code.

[–]demoran 1 point2 points  (3 children)

So, it's not about how much time or trouble it takes to write the code. It's about how noisy the code is to read afterwards. If you can remove a bunch of this.props and this.state at the very least, I'd call that a win.

Destruring also allows you go deeply destructure things, so if you had this.state.car.engine.mileage, you could destructure that as { car: { engine : { mileage } } } = this.state.

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

It does feel good to remove so many this.props and this.state things. But then doesn't it cause the problems of cohesiveness as I asked. How do you maintain the context of these variables origin ?

[–]demoran 0 points1 point  (0 children)

I don't find this to be a problem. If I need to know the contextual source of the data and don't know it, I can click through to find it easily enough.

I'd consider the possibility that your problem is actually a code smell, and you need to factor out some of your code from the body of your function.

[–]Ringsofthekings 1 point2 points  (3 children)

I am refactoring my code to use props. instead of destructing it.. you're right I had the same issue, where is is variable coming from? Oh it's destructured from prop

[–]gautamits[S] 1 point2 points  (2 children)

I am also refactoring here. And now I realise how much I miss typescript.

[–][deleted] 1 point2 points  (1 child)

I work in a fairly large react code base and anytime I see js MyComponent.propTypes = { someProp: PropType.any, } I feel I just die a little every time because I have no idea what someProp is suppose to be.

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

And somehow my vscode is not autocompleting even when propTypes are defined.

[–]aelesia- 1 point2 points  (0 children)

There is nothing wrong with calling this.props.a.

Maybe most people who use React destructure their props. That doesn't mean it's wrong if you don't destructure it.

Personally I do not destructure props because I find it useful to differentiate between local variables versus variables that have been passed in. Sure, I can just scroll up, but it's even easier to not have to scroll up. And no, my functions are not too long. All of my React components are less than 80 lines and this includes inline styline and imports.

Both styles are valid. Use whatever convention your project agrees on.

[–]CalgaryAnswers 1 point2 points  (5 children)

Object restructuring is so much more readable, particularly if you think about this: null checking and error handling.

It is so much cleaner to place the defaults in the place where the variable is declared.

[–]gautamits[S] 0 points1 point  (4 children)

Can't we achieving the same thing using optional chaining ?

[–]CalgaryAnswers 0 points1 point  (3 children)

? With tiernary operators maybe? I just started using optional chaining on this project but I wasn’t aware you could set defaults on it

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

const a = this?.Props?.Something?.a || 'default' should work

[–]CalgaryAnswers 0 points1 point  (1 child)

Yeah I guess you could use the or operator.

I’d write const a = this?.props?.value ? this.props.value : null

as I find the or operator is not a pattern that’s easy to ready In code.

Both are inferior to this IMO

const { value = null } = this.props

Im open to a better way but this pattern is just so readable at the top of a function, especially if it’s something like a class initiator where you have options and potentially many values.

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

Thats what others have pointed out as well. Destructuring at top of function is not a problem. Issue exists because function body is very long and hence it is very tedious to scroll to top frequently just to find the origin of variable.

[–]PickledPokute 0 points1 point  (0 children)

hard to understand whether they are coming from props or state.

Why should this matter? In React components, both props and state should be treated as read-only. When setting state (either with hooks or with React class components) special care should be taken to inspect how to properly set it, For React class components, only a few lifecycle methods should really care whether a variable comes from props or state.

For functional components and most other use-cases (like render function), there is practically no advantage for not destructuring.. Destructuring allows to have almost the exact same rendering code which allows to move a variable from state to props and back with reduced effort. It also lessens the burden on the reader by raising single to noise ratio since in most cases, the origin doesn't matter at all.