290 lines
8.7 KiB
Markdown
290 lines
8.7 KiB
Markdown
---
|
|
components:
|
|
- rx.match
|
|
---
|
|
|
|
```python exec
|
|
import reflex as rx
|
|
```
|
|
|
|
# Match
|
|
|
|
The `rx.match` feature in Reflex serves as a powerful alternative to `rx.cond` for handling conditional statements.
|
|
While `rx.cond` excels at conditionally rendering two components based on a single condition,
|
|
`rx.match` extends this functionality by allowing developers to handle multiple conditions and their associated components.
|
|
This feature is especially valuable when dealing with intricate conditional logic or nested scenarios,
|
|
where the limitations of `rx.cond` might lead to less readable and more complex code.
|
|
|
|
With `rx.match`, developers can not only handle multiple conditions but also perform structural pattern matching,
|
|
making it a versatile tool for managing various scenarios in Reflex applications.
|
|
|
|
## Basic Usage
|
|
|
|
The `rx.match` function provides a clear and expressive syntax for handling multiple
|
|
conditions and their corresponding components:
|
|
|
|
```python
|
|
rx.match(
|
|
condition,
|
|
(case_1, component_1),
|
|
(case_2, component_2),
|
|
...
|
|
default_component,
|
|
)
|
|
|
|
```
|
|
|
|
- `condition`: The value to match against.
|
|
- `(case_i, component_i)`: A Tuple of matching cases and their corresponding return components.
|
|
- `default_component`: A special case for the default component when the condition isnt matched by any of the match cases.
|
|
|
|
Example
|
|
|
|
```python demo exec
|
|
from typing import List
|
|
|
|
import reflex as rx
|
|
|
|
|
|
class MatchState(rx.State):
|
|
cat_breed: str = ""
|
|
animal_options: List[str] = ["persian", "siamese", "maine coon", "ragdoll", "pug", "corgi"]
|
|
|
|
|
|
def match_demo():
|
|
return rx.flex(
|
|
rx.match(
|
|
MatchState.cat_breed,
|
|
("persian", rx.text("Persian cat selected.")),
|
|
("siamese", rx.text("Siamese cat selected.")),
|
|
("maine coon", rx.text("Maine Coon cat selected.")),
|
|
("ragdoll", rx.text("Ragdoll cat selected.")),
|
|
rx.text("Unknown cat breed selected.")
|
|
),
|
|
rx.select.root(
|
|
rx.select.trigger(),
|
|
rx.select.content(
|
|
rx.select.group(
|
|
rx.foreach(MatchState.animal_options, lambda x: rx.select.item(x, value=x))
|
|
),
|
|
),
|
|
value=MatchState.cat_breed,
|
|
on_change=MatchState.set_cat_breed,
|
|
|
|
),
|
|
direction= "column",
|
|
gap= "2"
|
|
)
|
|
```
|
|
|
|
## Default Case
|
|
|
|
The default case in `rx.match` serves as a universal handler for scenarios where none of
|
|
the specified match cases aligns with the given match condition. Here are key considerations
|
|
when working with the default case:
|
|
|
|
- **Placement in the Match Function**: The default case must be the last non-tuple argument in the `rx.match` component.
|
|
All match cases should be enclosed in tuples; any non-tuple value is automatically treated as the default case. For example:
|
|
|
|
```python
|
|
rx.match(
|
|
MatchState.cat_breed,
|
|
("persian", rx.text("persian cat selected")),
|
|
rx.text("Unknown cat breed selected."),
|
|
("siamese", rx.text("siamese cat selected")),
|
|
)
|
|
```
|
|
|
|
The above code snippet will result in an error due to the misplaced default case.
|
|
|
|
- **Single Default Case**: Only one default case is allowed in the `rx.match` component.
|
|
Attempting to specify multiple default cases will lead to an error. For instance:
|
|
|
|
```python
|
|
rx.match(
|
|
MatchState.cat_breed,
|
|
("persian", rx.text("persian cat selected")),
|
|
("siamese", rx.text("siamese cat selected")),
|
|
rx.text("Unknown cat breed selected."),
|
|
rx.text("Another unknown cat breed selected.")
|
|
)
|
|
```
|
|
|
|
- **Optional Default Case for Component Return Values**: If the match cases in a `rx.match` component
|
|
return components, the default case can be optional. In this scenario, if a default case is
|
|
not provided, `rx.fragment` will be implicitly assigned as the default. For example:
|
|
|
|
```python
|
|
rx.match(
|
|
MatchState.cat_breed,
|
|
("persian", rx.text("persian cat selected")),
|
|
("siamese", rx.text("siamese cat selected")),
|
|
)
|
|
```
|
|
|
|
In this case, `rx.fragment` is the default case. However, not providing a default case for non-component
|
|
return values will result in an error:
|
|
|
|
```python
|
|
rx.match(
|
|
MatchState.cat_breed,
|
|
("persian", "persian cat selected"),
|
|
("siamese", "siamese cat selected"),
|
|
)
|
|
```
|
|
|
|
The above code snippet will result in an error as a default case must be explicitly
|
|
provided in this scenario.
|
|
|
|
## Handling Multiple Conditions
|
|
|
|
`rx.match` excels in efficiently managing multiple conditions and their corresponding components,
|
|
providing a cleaner and more readable alternative compared to nested `rx.cond` structures.
|
|
|
|
Consider the following example:
|
|
|
|
```python demo exec
|
|
from typing import List
|
|
|
|
import reflex as rx
|
|
|
|
|
|
class MultiMatchState(rx.State):
|
|
animal_breed: str = ""
|
|
animal_options: List[str] = ["persian", "siamese", "maine coon", "pug", "corgi", "mustang", "rahvan", "football", "golf"]
|
|
|
|
def multi_match_demo():
|
|
return rx.flex(
|
|
rx.match(
|
|
MultiMatchState.animal_breed,
|
|
("persian", "siamese", "maine coon", rx.text("Breeds of cats.")),
|
|
("pug", "corgi", rx.text("Breeds of dogs.")),
|
|
("mustang", "rahvan", rx.text("Breeds of horses.")),
|
|
rx.text("Unknown animal breed")
|
|
),
|
|
rx.select.root(
|
|
rx.select.trigger(),
|
|
rx.select.content(
|
|
rx.select.group(
|
|
rx.foreach(MultiMatchState.animal_options, lambda x: rx.select.item(x, value=x))
|
|
),
|
|
),
|
|
value=MultiMatchState.animal_breed,
|
|
on_change=MultiMatchState.set_animal_breed,
|
|
|
|
),
|
|
direction= "column",
|
|
gap= "2"
|
|
)
|
|
```
|
|
|
|
In a match case tuple, you can specify multiple conditions. The last value of the match case
|
|
tuple is automatically considered as the return value. It's important to note that a match case
|
|
tuple should contain a minimum of two elements: a match case and a return value.
|
|
The following code snippet will result in an error:
|
|
|
|
```python
|
|
rx.match(
|
|
MatchState.cat_breed,
|
|
("persian",),
|
|
("maine coon", rx.text("Maine Coon cat selected")),
|
|
)
|
|
```
|
|
|
|
## Usage as Props
|
|
|
|
Similar to `rx.cond`, `rx.match` can be used as prop values, allowing dynamic behavior for UI components:
|
|
|
|
```python demo exec
|
|
import reflex as rx
|
|
|
|
|
|
class MatchPropState(rx.State):
|
|
value: int = 0
|
|
|
|
def incr(self):
|
|
self.value += 1
|
|
|
|
def decr(self):
|
|
self.value -= 1
|
|
|
|
|
|
def match_prop_demo_():
|
|
return rx.flex(
|
|
rx.button("decrement", on_click=MatchPropState.decr, background_color="red"),
|
|
rx.badge(
|
|
MatchPropState.value,
|
|
color_scheme= rx.match(
|
|
MatchPropState.value,
|
|
(1, "red"),
|
|
(2, "blue"),
|
|
(6, "purple"),
|
|
(10, "orange"),
|
|
"green"
|
|
),
|
|
size="2",
|
|
),
|
|
rx.button("increment", on_click=MatchPropState.incr),
|
|
align_items="center",
|
|
direction= "row",
|
|
gap= "3"
|
|
)
|
|
```
|
|
|
|
In the example above, the background color property of the box component containing `State.value` changes to red when
|
|
`state.value` is 1, blue when its 5, green when its 5, orange when its 15 and black for any other value.
|
|
|
|
The example below also shows handling multiple conditions with the match component as props.
|
|
|
|
```python demo exec
|
|
import reflex as rx
|
|
|
|
|
|
class MatchMultiPropState(rx.State):
|
|
value: int = 0
|
|
|
|
def incr(self):
|
|
self.value += 1
|
|
|
|
def decr(self):
|
|
self.value -= 1
|
|
|
|
|
|
def match_multi_prop_demo_():
|
|
return rx.flex(
|
|
rx.button("decrement", on_click=MatchMultiPropState.decr, background_color="red"),
|
|
rx.badge(
|
|
MatchMultiPropState.value,
|
|
color_scheme= rx.match(
|
|
MatchMultiPropState.value,
|
|
(1, 3, 9, "red"),
|
|
(2, 4, 5, "blue"),
|
|
(6, 8, 12, "purple"),
|
|
(10, 15, 20, 25, "orange"),
|
|
"green"
|
|
),
|
|
size="2",
|
|
),
|
|
rx.button("increment", on_click=MatchMultiPropState.incr),
|
|
align_items="center",
|
|
direction= "row",
|
|
gap= "3"
|
|
)
|
|
```
|
|
|
|
```md alert warning
|
|
# Usage with Structural Pattern Matching
|
|
|
|
The `rx.match` component is designed for structural pattern matching. If the value of your match condition evaluates to a boolean (True or False), it is recommended to use `rx.cond` instead.
|
|
|
|
Consider the following example, which is more suitable for `rx.cond`:*
|
|
```
|
|
|
|
```python
|
|
rx.cond(
|
|
MatchPropState.value == 10,
|
|
"true value",
|
|
"false value"
|
|
)
|
|
```
|