Reputation: 127
I don't understand where the (val) is coming from in the returned arrow function. I get that the max/minLength is an arrow function taking in a argument set on the input field(3 and 25) and it's returning an arrow function with a parameter called val but where is the argument for this. I don't see where it is passed or coming from? I'm new to redux and redux-from so I'm not sure if it has something to do with this or just plain es6 JS. Thanks
import React, {Component} from 'react';
import {Breadcrumb, BreadcrumbItem, Button, Form, Row, Label, Col, FormFeedback} from 'reactstrap'
import {Link} from 'react-router-dom'
import {Control, LocalForm, Errors} from 'react-redux-form';
const required = (val) => val && val.length;
const maxLength = (len) => (val) => !(val) || (val.length <= len);
const minLength = (len) => (val) => (val) && (val.length >= len);
const isNumber = (val) => !isNaN(Number(val));
const validEmail = (val) => /^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}$/i.test(val);
class Contact extends Component {
handleSubmit = (values) => {
console.log("Current state is:" + JSON.stringify(values));
alert("Current state is:" + JSON.stringify(values));
}
render() {
<LocalForm onSubmit={(values) => this.handleSubmit(values)}>
<Row className="form-group">
<Label htmlFor="firstname" md={2}>First Name</Label>
<Col md={10}>
<Control.text model=".firstname" className="form-control" id="firstname" name="firstname"
placeholder="First Name"
validators={{required, minLength: minLength(3), maxLength: maxLength(25)}}/>
<Errors className="text-danger" model=".firstname" show="touched" messages={{
required: 'Required',
minLength: 'Must be greater than 2 Characters',
maxLength: 'Must be 25 Characters or less'
}}/>
</Col>
</Row>
Upvotes: 1
Views: 97
Reputation: 347
A function returning another function is used to generate different variations of that particular function to be applied to different scenarios.
It's almost like a function factory.
It might be easier to digest what's going on if you expand the arrow functions into the standard function syntax that they represent.
function maxLength(len) {
return function(val) {
return !(val) || (val.length <= len);
}
}
You can see that both arguments len
and val
are available on the third line for the conditional check. As far as the code in the innermost function is concerned, all the arguments taken before it are always fully available.
Below you can see how this maxLength
function can be used in practice to perform different checks based on what the first argument means to you.
If your script has a concept of what a "long" array is and what a "short" array is, this is how it would work:
const isShortArray = maxLength(2); // `isShortArray(val)` is now a new function
const isLongArray = maxLength(4); // same core function, different context
isShortArray(['foo']); // true, array `val` has fewer elements than number `len` which was set to 2
isShortArray(['foo', 'bar', 'baz']); // false, `len` of maxLength exceeded
isLongArray(['foo', 'bar', 'baz']); // true, this time `len` is different
isLongArray(['foo', 'bar', 'baz', 'qux', 'foo']); // false, val.length > 4 again
This is very similar to the technique called currying in functional programming languages. You can read more about that in JavaScript here.
Upvotes: 2