const range = (start, end, step = 1) => {
let output = [];
if (typeof end === 'undefined') {
end = start;
start = 0;
}
for (let i = start; i < end; i += step) {
output.push(i);
}
return output;
};
Link to this headingContext
Sometimes, you want to render a sequence of numbers. For example, the pagination widget at the bottom of Google search results:
Perhaps even more commonly, you want to render something a handful of times. Maybe you want to generate 5 particles, or a bunch of background lines for a graph.
In React, this matter is complicated a bit, because we need an array we can map over. Essentially, I want to be able to do something like this:
const PaginationWidget = () => {
return (
<div>
{range(1, 11).map((num) => (
<PageNum key={num}>{num}</PageNum>
))}
</div>
);
};
I'm not able to use a for
loop, since we need to render expressions within JSX.
This range
utility gives me a concise, functional way to solve for these kinds of problems.
Link to this headingUsage
This utility can be used in several ways.
You can pass a single number, to generate a range from 0 through that number:
range(5); // [0, 1, 2, 3, 4]
You can pass two numbers, to generate a range from start to finish:
range(5, 10); // [5, 6, 7, 8, 9]
Finally, you can pass a third "step" argument, if you want to change the gap between numbers:
range(0, 6, 2); // [0, 2, 4]
range(10, 12, 0.5); // [10, 10.5, 11, 11.5]
You'll notice that the array produced is inclusive of the starting number, but exclusive of the ending number. range(10, 20)
includes 10, but does not include 20. This is done intentionally, to match the behaviour of JavaScript methods like slice(opens in new tab).
Link to this headingExplanation
Iterating from a start value to an end value, with a given step, is exactly the problem that for
loops were designed to solve. Our range
function is really just a thin wrapper around this common "vanilla" pattern!
One possibly surprising bit is this:
if (typeof end === undefined) {
end = start;
start = 0;
}
This check exists so that we can call range
with a single value, like range(4)
. Instead of being used as the start
value, we're copying this value to end
, and setting start
to 0. This is a quality-of-life thing, to make it a small bit easier to use.
Last updated on
March 16th, 2023