Skip to content

Quick start

OverviewΒΆ

Welcome to the ReactPy documentation! This page will give you an introduction to the 80% of React concepts that you will use on a daily basis.

You will learn

  • How to create and nest components
  • How to add markup and styles
  • How to display data
  • How to render conditions and lists
  • How to respond to events and update the screen
  • How to share data between components

Creating and nesting componentsΒΆ

React apps are made out of components. A component is a piece of the UI (user interface) that has its own logic and appearance. A component can be as small as a button, or as large as an entire page.

React components are Python functions that return markup:

@component
def my_button():
    return html.button("I'm a button!")

Now that you've declared my_button, you can nest it into another component:

@component
def my_app():
    return html.div(
        html.h1("Welcome to my app"),
        my_button(),
    )

Have a look at the result:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
from reactpy import component, html


@component
def my_button():
    return html.button("I'm a button!")


@component
def my_app():
    return html.div(
        html.h1("Welcome to my app"),
        my_button(),
    )
1
# TODO

Adding stylesΒΆ

In React, you specify a CSS class with className. It works the same way as the HTML class attribute:

html.img({"className": "avatar"})

Then you write the CSS rules for it in a separate CSS file:

/* In your CSS */
.avatar {
    border-radius: 50%;
}

React does not prescribe how you add CSS files. In the simplest case, you'll add a <link> tag to your HTML. If you use a build tool or web framework, consult its documentation to learn how to add a CSS file to your project.

Displaying dataΒΆ

You can fetch data from a variety of sources and directly embed it into your components. You can also use the style attribute when your styles depend on JavaScript variables.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
from reactpy import component, html

user = {
    "name": "Hedy Lamarr",
    "image_url": "https://i.imgur.com/yXOvdOSs.jpg",
    "image_size": 90,
}


@component
def profile():
    return html.div(
        html.h3(user["name"]),
        html.img(
            {
                "className": "avatar",
                "src": user["image_url"],
                "alt": f"Photo of {user['name']}",
                "style": {
                    "width": user["image_size"],
                    "height": user["image_size"],
                },
            }
        ),
    )
1
2
3
4
5
6
7
.avatar {
    border-radius: 50%;
}

.large {
    border: 4px solid gold;
}
1
# TODO

Conditional renderingΒΆ

In React, there is no special syntax for writing conditions. Instead, you'll use the same techniques as you use when writing regular Python code. For example, you can use an if statement to conditionally include components:

@component
def my_component():
    if is_logged_in:
        content = admin_panel()
    else:
        content = login_form()
    return html.div(content)

If you prefer more compact code, you can use the ternary operator.:

@component
def my_component():
    return html.div(admin_panel() if is_logged_in else login_form())

When you don't need the else branch, you can also use a shorter logical and syntax:

@component
def my_component():
    return html.div(is_logged_in and admin_panel())

All of these approaches also work for conditionally specifying attributes. If you're unfamiliar with some of this Python syntax, you can start by always using if...else.

Rendering listsΒΆ

You will rely on Python features like for loop and list comprehension to render lists of components.

For example, let's say you have an array of products:

products = [
    {"title": "Cabbage", "id": 1},
    {"title": "Garlic", "id": 2},
    {"title": "Apple", "id": 3},
]

Inside your component, use list comprehension to transform an array of products into an array of <li> items:

list_items = [html.li({"key": product["id"]}, product["title"]) for product in products]

Notice how <li> has a key attribute. For each item in a list, you should pass a string or a number that uniquely identifies that item among its siblings. Usually, a key should be coming from your data, such as a database ID. React uses your keys to know what happened if you later insert, delete, or reorder the items.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
from reactpy import component, html

products = [
    {"title": "Cabbage", "is_fruit": False, "id": 1},
    {"title": "Garlic", "is_fruit": False, "id": 2},
    {"title": "Apple", "is_fruit": True, "id": 3},
]


@component
def shopping_list():
    list_items = [
        html.li(
            {
                "key": product["id"],
                "style": {"color": "magenta" if product["is_fruit"] else "darkgreen"},
            },
            product["title"],
        )
        for product in products
    ]

    return html.ul(list_items)
1
# TODO

Responding to eventsΒΆ

You can respond to events by declaring event handler functions inside your components:

@component
def my_button():
    def handle_click(event):
        print("You clicked me!")

    return html.button(
        {"onClick": handle_click},
        "Click me",
    )

Notice how "onClick": handle_click has no parentheses at the end! Do not call the event handler function: you only need to pass it down. React will call your event handler when the user clicks the button.

Updating the screenΒΆ

Often, you'll want your component to "remember" some information and display it. For example, maybe you want to count the number of times a button is clicked. To do this, add state to your component.

First, import use_state from React:

from reactpy import use_state

Now you can declare a state variable inside your component:

@component
def my_button():
    count, set_count = use_state(0)
    # ...

You’ll get two things from use_state: the current state (count), and the function that lets you update it (set_count). You can give them any names, but the convention is to write something, set_something = ....

The first time the button is displayed, count will be 0 because you passed 0 to use_state(). When you want to change state, call set_count() and pass the new value to it. Clicking this button will increment the counter:

@component
def my_button():
    count, set_count = use_state(0)

    def handle_click(event):
        set_count(count + 1)

    return html.button({"onClick": handle_click}, f"Clicked {count} times")

React will call your component function again. This time, count will be 1. Then it will be 2. And so on.

If you render the same component multiple times, each will get its own state. Click each button separately:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
from reactpy import component, html, use_state


@component
def my_app():
    return html.div(
        html.h1("Counters that update separately"),
        my_button(),
        my_button(),
    )


@component
def my_button():
    count, set_count = use_state(0)

    def handle_click(event):
        set_count(count + 1)

    return html.button({"onClick": handle_click}, f"Clicked {count} times")
1
2
3
4
button {
    display: block;
    margin-bottom: 5px;
}
1
# TODO

Notice how each button "remembers" its own count state and doesn't affect other buttons.

Using HooksΒΆ

Functions starting with use are called Hooks. use_state is a built-in Hook provided by React. You can find other built-in Hooks in the API reference. You can also write your own Hooks by combining the existing ones.

Hooks are more restrictive than other functions. You can only call Hooks at the top of your components (or other Hooks). If you want to use use_state in a condition or a loop, extract a new component and put it there.

Sharing data between componentsΒΆ

In the previous example, each my_button had its own independent count, and when each button was clicked, only the count for the button clicked changed:

However, often you'll need components to share data and always update together.

To make both my_button components display the same count and update together, you need to move the state from the individual buttons "upwards" to the closest component containing all of them.

In this example, it is my_app.

Now when you click either button, the count in my_app will change, which will change both of the counts in my_button. Here's how you can express this in code.

First, move the state up from my_button into my_app:

@component
def my_app():
    count, set_count = use_state(0)

    def handle_click(event):
        set_count(count + 1)

    return html.div(
        html.h1("Counters that update separately"),
        my_button(),
        my_button(),
    )


@component
def my_button():
    # ... we're moving code from here ...

Then, pass the state down from my_app to each my_button, together with the shared click handler. You can pass information to my_button using props:

@component
def my_app():
    count, set_count = use_state(0)

    def handle_click(event):
        set_count(count + 1)

    return html.div(
        html.h1("Counters that update together"),
        my_button(count, handle_click),
        my_button(count, handle_click),
    )

The information you pass down like this is called props. Now the my_app component contains the count state and the handle_click event handler, and passes both of them down as props to each of the buttons.

Finally, change my_button to read the props you have passed from its parent component:

@component
def my_button(count, on_click):
    return html.button({"onClick": on_click}, f"Clicked {count} times")

When you click the button, the on_click handler fires. Each button's on_click prop was set to the handle_click function inside my_app, so the code inside of it runs. That code calls set_count(count + 1), incrementing the count state variable. The new count value is passed as a prop to each button, so they all show the new value. This is called "lifting state up". By moving state up, you've shared it between components.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
from reactpy import component, html, use_state


@component
def my_app():
    count, set_count = use_state(0)

    def handle_click(event):
        set_count(count + 1)

    return html.div(
        html.h1("Counters that update together"),
        my_button(count, handle_click),
        my_button(count, handle_click),
    )


@component
def my_button(count, on_click):
    return html.button({"onClick": on_click}, f"Clicked {count} times")
1
2
3
4
button {
    display: block;
    margin-bottom: 5px;
}
1
# TODO

Next StepsΒΆ

By now, you know the basics of how to write React code!

Check out the Tutorial to put them into practice and build your first mini-app with React.


Last update: March 15, 2025
Authors: Archmonger