DEV Community

Cover image for js❤️ - Arrow functions y funciones de primera clase
Javi Carrasco
Javi Carrasco

Posted on • Edited on

js❤️ - Arrow functions y funciones de primera clase

Arrow functions y funciones de primera clase

Las arrow functions nos permiten definir funciones de una forma más compacta.

// funciones normales function sum(a, b) { return a + b; } // arrow function const sum = (a, b) => a + b; 
Enter fullscreen mode Exit fullscreen mode

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

const nums = [1, 2, 3]; const squares = nums.map((n) => n * n); 
Enter fullscreen mode Exit fullscreen mode

Para que una arrow function devuelva un objeto debemos ponerlo entre paréntesis

const merge = (obj1, obj2) => ({ ...obj1, ...obj2 }); 
Enter fullscreen mode Exit fullscreen mode

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

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

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

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>  ); } 
Enter fullscreen mode Exit fullscreen mode

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)

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 
Enter fullscreen mode Exit fullscreen mode

Podemos ahorrarnos crear funciones intermedias

const Wrapper = ({ value, onChange }) => ( <div> <Input value={value} onChange={(val) => onChange(val)} /> {/* ⛔️ */}  </div> ); 
Enter fullscreen mode Exit fullscreen mode

Puede ser escrita como

const Wrapper = ({ value, onChange }) => ( <div> <Input value={value} onChange={onChange} />  </div> ); 
Enter fullscreen mode Exit fullscreen mode

O mejor incluso, ya que las props son las mismas

const Wrapper = (props) => ( <div> <Input {...props} />  </div> ); 
Enter fullscreen mode Exit fullscreen mode

Currying

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

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)} /> ) 
Enter fullscreen mode Exit fullscreen mode

Siguiente - map, reduce, forEach, find y filter →

Top comments (0)