Callbacks are a great tool to achieve SRP. For ex. the following function is responsbile for submitting forms
and nothing else.
// SRP
const submitForm = ({apiUrl, payload, onSuccess, onFailure}) => {
fetch(apiUrl, payload)
.then((res) => {
onSucces(res)
})
.catch(err => {
onFailure(err);
})
}
// submit to digio-api - functional programming
const submitFormDigio = ({payload, onSuccess, onFailure}) => {
submitForm({
apiUrl: "https://digio.com/api/submit",
payload,
onSuccess,
onFailure
})
}
// implementation - note that instead of handling notification inside
// submitForm method; we are handling it outside of it. This is one way
// how callbacks helps us in SRP
const onFailure = (err) => setErrors([err])
submitForm({
payload: {},
onSuccess: () => notify("succes", "Form is submitted"),
onFailure
})
// without HOC
const greaterThan5Words = word => word.length > 5;
// We may also want to have a dynamic length. To do that we can create an HOC:
const createLengthTest = minLength => word => word.length > minLength
// Now we can re-write our greaterThan5Words
const greaterThan5WordsNew = createLengthTest(5)
// The added advantage of this is that now we can create more variants:
const greaterThan3Words = createLengthTest(6)
const greaterThan20Words = createLengthTest(20) // etc.
- Earlier only the
word
argument was dynamic; wheras the minLength was fixed. After introductingHOC
; even theminLength
is dynamic. So now we have more flexibility. - This pattern can be very useful for new approach implementation over legacy code.
const arr = [1,2,3,4,5]
const newArr = arr.slice() // clones arr
const arr = [1,2,3,4,5];
const reversedArray = arr.slice().reverse()
const add = (x,y,z) => x + y + z
// curry-in the first argument
const add1 = add.bind(null, 1);
console.log(add1(2,3)) // 6
// curry-in the first 2 arguments
const add1And2 = add.bind(null, 1, 2);
console.log(add1And2(3)) // 6
const reduceToDouble = (acc, num) => [
...acc,
num * 2
]
const arr1 = [1,2,3].reduce(reduceToDouble, []) // [2, 4, 6]
const arr2 = [3,4,5].reduce(reduceToDouble, []) // [6, 8, 10]
// Notice in the above example we have to keep pasing the empty array
// A clearner way to do this:
const reduceToDouble = arr => arr.reduce((acc, num) => [...acc, num * 2])
const arr1 = reduceToDouble([1,2,3])
const arr2 = reduceToDouble([3,4,5])
In this approach we do not have to call the reduce
method each time; nor the empty array []
.
Instead we simply call a single method reduceToDouble
on the array
.
Always look for ways to simplify conditional statements with tertiary. For ex:
if(somethingIsTrue) {
executeFunc8()
} else {
executeFunc9()
}
// can be replaced with:
somethingIsTrue ? executeFunc8() : executeFunc9();