js❤️ - Arrow functions y funciones de primera clase
Tags: javascript, es6, react, spanish
Published: 2022-02-05 11:09:31


## Arrow functions y funciones de primera clase

Las _arrow functions_ nos permiten definir funciones de una forma más compacta.

```js
// funciones normales
function sum(a, b) {
  return a + b;
}

// arrow function
const sum = (a, b) => a + b;
```

Lo que facilita definir funciones y pasarlas como argumentos en un solo paso

```jsx
const nums = [1, 2, 3];
const squares = nums.map((n) => n * n);
```

Para que una _arrow function_ devuelva un objeto debemos ponerlo entre paréntesis

```js
const merge = (obj1, obj2) => ({ ...obj1, ...obj2 });
```

Cuidado porque podemos crear funciones nuevas cuando no lo deseamos.
En el siguiente ejemplo el componente `Screen` pasa una nueva función a `Button` cada vez que `Screen` se re-renderiza.
Y esto provoca que cada vez que el usuario escribe una letra en `Input` se re-renderice `Button`

```js
function Screen() {
  const [value, setValue] = useState("");
  const [loading, setLoading] = useState(false);
  return (
    <div>
      <Input value={value} onChange={setValue} />
      <Button onclick={() => setLoading(true)} /> {/* ⛔️ */}
    </div>
  );
}
```

React nos permite solucionarlo con el _hook_ `useCallback` que mantiene la función siempre igual para esta instancia del componente `Screen`.

```js
function Screen() {
  const [value, setValue] = useState("");
  const [loading, setLoading] = useState(false);
  const activateLoading = useCallback(() => setLoading(true), [setLoading]);
  return (
    <div>
      <Input value={value} onChange={setValue} />
      <Button onclick={activateLoading} />
    </div>
  );
}
```

Además JavaScript tiene _first-class functions_. Eso significa que las funciones se tratan como una variable, pueden ser pasadas como argumento y devueltas en otras funciones.
Esto da lugar a algunos patrones interesantes:

Funciones que devuelven otras funciones (atención a la _closure_)

```js
const logger = (module) => (msg) => console.log(`${module}: ${msg}`);

const log = logger("BeneficiaryApi");

log("Requested Beneficiaries");
// "BeneficiaryApi: Requested Beneficiaries

log("Beneficiaries request successful");
// "BeneficiaryApi: Beneficiaries request successful
```

Podemos ahorrarnos crear funciones intermedias

```js
const Wrapper = ({ value, onChange }) => (
  <div>
    <Input value={value} onChange={(val) => onChange(val)} /> {/* ⛔️ */}
  </div>
);
```

Puede ser escrita como

```js
const Wrapper = ({ value, onChange }) => (
  <div>
    <Input value={value} onChange={onChange} />
  </div>
);
```

O mejor incluso, ya que las _props_ son las mismas

```js
const Wrapper = (props) => (
  <div>
    <Input {...props} />
  </div>
);
```

### Currying
Consiste en utilizar _closures_ para generar funciones que llaman a otras funciones con algunos parámetros fijos. Por ejemplo:

```js
const User = ({userId, name, address}) => (
  const update = (attr, value) => updateUser(userId, attr, value);
  <Input 
    label="Name" 
    value={name} 
    onChange={val => update("name", val)}
  />
  <Input 
    label="Address" 
    value={address} 
    onChange={val => update("address", val)}
  />
)
```

[Siguiente - map, reduce, forEach, find y filter →](https://dev.to/jacarma/js-map-foreach-find-filter-reduce-3h0o)