Reflex's Var System
Motivation
Reflex supports some basic operations in state variables on the frontend. Reflex automatically converts variable operations from Python into a JavaScript equivalent.
Here's an example of a Reflex conditional in Python that returns "Pass" if the threshold is equal to or greater than 50 and "Fail" otherwise:
rx.cond( State.threshold >= 50, "Pass", "Fail", )
The conditional to roughly the following in Javascript:
state.threshold >= 50 ? "Pass" : "Fail";
Overview
Simply put, a Var
in Reflex represents a Javascript expression.
If the type is known, it can be any of the following:
NumberVar
represents an expression that evaluates to a Javascriptnumber
.NumberVar
can support both integers and floating point valuesBooleanVar
represents a boolean expression. For example:false
,3 > 2
.StringVar
represents an expression that evaluates to a string. For example:'hello'
,(2).toString()
.ArrayVar
represents an expression that evaluates to an array object. For example:[1, 2, 3]
,'words'.split()
.ObjectVar
represents an expression that evaluates to an object. For example:{a: 2, b: 3}
,{deeply: \{nested: \{value: false}}}
.NoneVar
represent null values. These can be eitherundefined
ornull
.
Creating Vars
State fields are converted to Var
by default. Additionally, you can create a Var
from Python values using rx.Var.create()
:
rx.Var.create(4) # NumberVar rx.Var.create("hello") # StringVar rx.Var.create([1, 2, 3]) # ArrayVar
If you want to explicitly create a Var
from a raw Javascript string, you can instantiate rx.Var
directly:
rx.Var("2", _var_type=int).guess_type() # NumberVar
In the example above, .guess_type()
will attempt to downcast from a generic Var
type into NumberVar
.
For this example, calling the function .to(int)
can also be used in place of .guess_type()
.
Operations
The Var
system also supports some other basic operations.
For example, NumberVar
supports basic arithmetic operations like +
and -
, as in Python.
It also supports comparisons that return a BooleanVar
.
Custom Var
operations can also be defined:
from reflex.vars import var_operation, var_operation_return, ArrayVar, NumberVar @var_operation def multiply_array_values(a: ArrayVar): return var_operation_return( js_expression=f"{a}.reduce((p, c) => p * c, 1)", var_type=int, ) def factorial(value: NumberVar): return rx.cond( value <= 1, 1, multiply_array_values(rx.Var.range(1, value+1)) )
Use js_expression
to pass explicit JavaScript expressions; in the multiply_array_values
example, we pass in a JavaScript expression that calculates the product of all elements in an array called a
by using the reduce method to multiply each element with the accumulated result, starting from an initial value of 1.
Later, we leverage rx.cond
in the' factorial' function, we instantiate an array using the range
function, and pass this array to multiply_array_values
.