reflex/docs/getting-started/introduction.md
2024-02-26 17:18:28 +01:00

227 lines
5.8 KiB
Markdown

```python exec
import reflex as rx
from pcweb import constants, styles
from pcweb.templates.docpage import doccode
from pcweb.pages.docs import tutorial
from pcweb.pages.docs import getting_started
from pcweb.pages.docs import wrapping_react
from pcweb.pages.docs.library import library
from pcweb.pages.docs import vars
```
<!-- TODO how do we consistently rename page title? -->
# Introduction
**Reflex** is an open-source framework for quickly building beautiful, interactive web applications in **pure Python**.
## Goals
```md section
# Pure Python
Use Python for everything. Don't worry about learning a new language.
# Easy to Learn
Build and share your first app in minutes. No web development experience required.
# Full Flexibility
Remain as flexible as traditional web frameworks. Reflex is easy to use, yet allows for advanced use cases.
Build anything from small data science apps to large, multi-page websites. **This entire site was built and deployed with Reflex!**
# Batteries Included
No need to reach for a bunch of different tools. Reflex handles the user interface, server-side logic, and deployment of your app.
```
## An example: Make it count
Here, we go over a simple counter app that lets the user count up or down.
<!-- TODO use radix components, to allow more concise styling - e.g. all them props -->
```python exec
class CounterExampleState(rx.State):
count: int = 0
def increment(self):
self.count += 1
def decrement(self):
self.count -= 1
```
```python demo box
rx.hstack(
rx.button(
"Decrement",
color_scheme="ruby",
on_click=CounterExampleState.decrement,
),
rx.heading(CounterExampleState.count, font_size="2em"),
rx.button(
"Increment",
color_scheme="grass",
on_click=CounterExampleState.increment,
),
spacing="4",
)
```
Here is the full code for this example:
```python
import reflex as rx
class State(rx.State):
count: int = 0
def increment(self):
self.count += 1
def decrement(self):
self.count -= 1
def index():
return rx.hstack(
rx.button(
"Decrement",
color_scheme="ruby",
on_click=State.decrement,
),
rx.heading(State.count, font_size="2em"),
rx.button(
"Increment",
color_scheme="grass",
on_click=State.increment,
),
spacing="4",
)
app = rx.App()
app.add_page(index)
```
## The Structure of a Reflex App
Let's break this example down.
### Import
```python
import reflex as rx
```
We begin by importing the `reflex` package (aliased to `rx`). We reference Reflex objects as `rx.*` by convention.
### State
```python
class State(rx.State):
count: int = 0
```
The state defines all the variables (called **[vars]({vars.base_vars.path})**) in an app that can change, as well as the functions (called **[event_handlers](#event-handlers)**) that change them.
Here our state has a single var, `count`, which holds the current value of the counter. We initialize it to `0`.
### Event Handlers
```python
def increment(self):
self.count += 1
def decrement(self):
self.count -= 1
```
Within the state, we define functions, called **event handlers**, that change the state vars.
Event handlers are the only way that we can modify the state in Reflex.
They can be called in response to user actions, such as clicking a button or typing in a text box.
These actions are called **events**.
Our counter app has two event handlers, `increment` and `decrement`.
### User Interface (UI)
```python
def index():
return rx.hstack(
rx.button(
"Decrement",
color_scheme="ruby",
on_click=State.decrement,
),
rx.heading(State.count, font_size="2em"),
rx.button(
"Increment",
color_scheme="grass",
on_click=State.increment,
),
spacing="4",
)
```
This function defines the app's user interface.
We use different components such as `rx.hstack`, `rx.button`, and `rx.heading` to build the frontend. Components can be nested to create complex layouts, and can be styled using the full power of CSS.
Reflex comes with [50+ built-in components]({library.path}) to help you get started.
We are actively adding more components. Also, it's easy to [wrap your own React components]({wrapping_react.overview.path}).
```python
rx.heading(State.count, font_size="2em"),
```
Components can reference the app's state vars.
The `rx.heading` component displays the current value of the counter by referencing `State.count`.
All components that reference state will reactively update whenever the state changes.
```python
rx.button(
"Decrement",
color_scheme="ruby",
on_click=State.decrement,
),
```
Components interact with the state by binding events triggers to event handlers.
For example, `on_click` is an event that is triggered when a user clicks a component.
The first button in our app binds its `on_click` event to the `State.decrement` event handler. Similarly the second button binds `on_click` to `State.increment`.
In other words, the sequence goes like this:
* User clicks "increment" on the UI.
* `on_click` event is triggered.
* Event handler `State.increment` is called.
* `State.count` is incremented.
* UI updates to reflect the new value of `State.count`.
### Add pages
Next we define our app and add the counter component to the base route.
```python
app = rx.App()
app.add_page(index)
```
## Next Steps
🎉 And that's it!
We've created a simple, yet fully interactive web app in pure Python.
By continuing with our documentation, you will learn how to building awesome apps with Reflex.
For a glimpse of the possibilities, check out these resources:
* For a more real-world example, check out the [tutorial]({tutorial.intro.path}).