DEV Community

Discussion on: Whenever we see (d) => setData(d), what can we think about?

Collapse
 
tbroyer profile image
Thomas Broyer

This is very error prone though!
As soon as the caller or callback can pass/take different arguments. And it will bite you as soon as you want to change the API (start passing more arguments to the callback, start taking more arguments in the callback)

Simple counter-example:

let ints = ["1","2","10","16","20"].map(parseInt);
Enter fullscreen mode Exit fullscreen mode
Collapse
 
kennethlum profile image
Kenneth Lum • Edited

parseInt is the classic example... in this case the extra index passed into parseInt... for setData() it should be ok IMHO

Collapse
 
tbroyer profile image
Thomas Broyer

If you use setData with Array.prototype.map, it makes it harder to add an (optional) second argument to setData without breaking .map(setData); whereas .map(d => setData(d)) would work just as well, always passing a single argument to setData.

And using .then(parseInt) will make it harder for TC39 to possibly add a second argument to the ifFulfilled callback without breaking existing websites; whereas .then(d => parseInt(d)) would continue to work just as well, ignoring the second argument.

Using the function directly as the callback only works if it's been designed for that exact usage only.

Given all that, one should use d => setData(d) as rule of thumb, making it explicit which arguments are expected and used.

Thread Thread
 
kennethlum profile image
Kenneth Lum

I guess that can make sense. When I first looked at some code that was like

fetch(" ... ")
  .then(res => res.json())
  .then(setData)
  .catch(console.error);
Enter fullscreen mode Exit fullscreen mode

I just thought it was kind of cool. I guess maybe just as something we are aware of.

Collapse
 
lionelrowe profile image
lionel-rowe

It's only error prone if the outer function calls the callback with arity greater than 1, though. It's perfectly safe with .then chains, because .then only passes a single value, the value the promise resolves to.

Collapse
 
sargalias profile image
Spyros Argalias • Edited

Fair point. You have to be careful when the number of arguments passed can be a problem. However the majority of the time, I use functions that only accept a single argument or on something like .then or .catch which only passes a single argument, so I prefer OP's way for that.

I can see the problem with inconsistency though, which might lead to the type of errors you mentioned. As they say, "consistency over perfection", which would lead me to choose your method if we had to pick just one.

But, in my opinion, the best solution is for everyone in the codebase to be comfortable with functional programming (which is probably not realistic). If that was the case, then the parseInt solution might be something like this:

import {unary} from 'ramda';
const ints = ["1","2","10","16","20"].map(unary(parseInt));

// or

import {map} from 'ramda';
const ints = map(parseInt, ["1","2","10","16","20"]);
Enter fullscreen mode Exit fullscreen mode