Racket parameters can be used to provide dynamic scoping (instead of the usual lexical scoping). It also provide thread local store.
If Racket didn't have parameters, then I am sure, more programs would use
global variables.
As an example of a use case, consider a program that draws points, lines, rectangles etc. Each shape has a function that draws the shape.
The user of course want to control the color used to draw the shape.
One option is to let all functions have a color argument as input.
It doesn't take long to realize, that most often one draws a lot of shapes
using the same color - so instead of all functions taking an extra argument,
we want to store the current color "outside" of the drawing functions.
We can store the current color in a global variable, but we need to consider
what happens if we set the current color, call a helper function, and continues to draw. The helper function could potentially change the current color, so before
calling helpers, we need to store the old value, and after we need to restore the value.
Using a parameter is easier, since the parameterize form will restore the
temporarily changed bindings back to the original at the right time.
As a side-note parameters works correctly in the presence of continuations,
which can be used to jump back into a some middle part of a computation.
There is an explanation of dynamic scope here:
https://en.wikipedia.org/wiki/Scope_(computer_science)#Dynamic_scoping
The final section of parameters in the Guide sums of the advantages of parameters
over global variables:
https://docs.racket-lang.org/guide/parameterize.html