Skip to content

Hooks

Overview

Prefabricated hooks can be used within your components.py to help simplify development.

Note

Looking for standard React hooks?

This package only contains Django specific hooks. Standard hooks can be found within reactive-python/reactpy.


Database Hooks


Use Query

Execute functions in the background and return the result, typically to read data from the Django ORM.

The default postprocessor expects your query function to return a Django Model or QuerySet. This needs to be changed or disabled to execute other types of queries.

Query functions can be sync or async.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
from channels.db import database_sync_to_async
from example.models import TodoItem
from reactpy import component, html
from reactpy_django.hooks import use_query


async def get_items():
    return await database_sync_to_async(TodoItem.objects.all)()


@component
def todo_list():
    item_query = use_query(get_items)

    if item_query.loading:
        rendered_items = html.h2("Loading...")
    elif item_query.error or not item_query.data:
        rendered_items = html.h2("Error when loading!")
    else:
        rendered_items = html.ul([html.li(item, key=item) for item in item_query.data])

    return html.div("Rendered items: ", rendered_items)
1
2
3
4
5
from django.db.models import CharField, Model


class TodoItem(Model):
    text: CharField = CharField(max_length=255)
See Interface

Parameters

Name Type Description Default
options QueryOptions | None An optional QueryOptions object that can modify how the query is executed. None
query Callable[_Params, _Result | None] A callable that returns a Django Model or QuerySet. N/A
*args _Params.args Positional arguments to pass into query. N/A
**kwargs _Params.kwargs Keyword arguments to pass into query. N/A

Returns

Type Description
Query[_Result | None] An object containing loading/error states, your data (if the query has successfully executed), and a refetch callable that can be used to re-run the query.
How can I provide arguments to my query function?

*args and **kwargs can be provided to your query function via use_query parameters.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
from reactpy import component
from reactpy_django.hooks import use_query


def example_query(value: int, other_value: bool = False):
    ...


@component
def my_component():
    query = use_query(
        example_query,
        123,
        other_value=True,
    )

    return str(query.data)
How can I customize this hook's behavior?

This hook accepts a options: QueryOptions parameter that can be used to customize behavior.

Below are the settings that can be modified via these QueryOptions.


thread_sensitive

Whether to run your synchronous query function in thread-sensitive mode. Thread-sensitive mode is turned on by default due to Django ORM limitations. See Django's sync_to_async docs docs for more information.

This setting only applies to sync query functions, and will be ignored for async functions.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
from reactpy import component
from reactpy_django.hooks import use_query
from reactpy_django.types import QueryOptions


def execute_thread_safe_operation():
    """This is an example query function that does some thread-safe operation."""
    pass


@component
def my_component():
    query = use_query(
        QueryOptions(thread_sensitive=False),
        execute_thread_safe_operation,
    )

    if query.loading or query.error:
        return None

    return str(query.data)

postprocessor

By default, automatic recursive fetching of ManyToMany or ForeignKey fields is enabled within the django_query_postprocessor. This is needed to prevent SynchronousOnlyOperation exceptions when accessing these fields within your ReactPy components.

However, if you...

  1. Want to use this hook to defer IO intensive tasks to be computed in the background
  2. Want to to utilize use_query with a different ORM

... then you can either set a custom postprocessor, or disable all postprocessing behavior by modifying the QueryOptions.postprocessor parameter. In the example below, we will set the postprocessor to None to disable postprocessing behavior.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
from reactpy import component
from reactpy_django.hooks import use_query
from reactpy_django.types import QueryOptions


def execute_io_intensive_operation():
    """This is an example query function that does something IO intensive."""
    pass


@component
def my_component():
    query = use_query(
        QueryOptions(postprocessor=None),
        execute_io_intensive_operation,
    )

    if query.loading or query.error:
        return None

    return str(query.data)

If you wish to create a custom postprocessor, you will need to create a callable.

The first argument of postprocessor must be the query data. All proceeding arguments are optional postprocessor_kwargs (see below). This postprocessor must return the modified data.

 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
26
27
28
29
30
31
from reactpy import component
from reactpy_django.hooks import use_query
from reactpy_django.types import QueryOptions


def my_postprocessor(data, example_kwarg=True):
    if example_kwarg:
        return data

    return dict(data)


def execute_io_intensive_operation():
    """This is an example query function that does something IO intensive."""
    pass


@component
def my_component():
    query = use_query(
        QueryOptions(
            postprocessor=my_postprocessor,
            postprocessor_kwargs={"example_kwarg": False},
        ),
        execute_io_intensive_operation,
    )

    if query.loading or query.error:
        return None

    return str(query.data)

postprocessor_kwargs

By default, automatic recursive fetching of ManyToMany or ForeignKey fields is enabled within the django_query_postprocessor. This is needed to prevent SynchronousOnlyOperation exceptions when accessing these fields within your ReactPy components.

However, if you have deep nested trees of relational data, this may not be a desirable behavior. In these scenarios, you may prefer to manually fetch these relational fields using a second use_query hook.

You can disable the prefetching behavior of the default postprocessor (located at reactpy_django.utils.django_query_postprocessor) via the QueryOptions.postprocessor_kwargs parameter.

 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
26
27
28
29
30
31
from example.models import TodoItem
from reactpy import component
from reactpy_django.hooks import use_query
from reactpy_django.types import QueryOptions


def get_model_with_relationships():
    """This is an example query function that gets `MyModel` which has a ManyToMany field, and
    additionally other models that have formed a ForeignKey association to `MyModel`.

    ManyToMany Field: `many_to_many_field`
    ForeignKey Field: `foreign_key_field_set`
    """
    return TodoItem.objects.get(id=1)


@component
def my_component():
    query = use_query(
        QueryOptions(
            postprocessor_kwargs={"many_to_many": False, "many_to_one": False}
        ),
        get_model_with_relationships,
    )

    if query.loading or query.error or not query.data:
        return None

    # By disabling `many_to_many` and `many_to_one`, accessing these fields will now
    # generate a `SynchronousOnlyOperation` exception
    return f"{query.data.many_to_many_field} {query.data.foriegn_key_field_set}"

Note: In Django's ORM design, the field name to access foreign keys is postfixed with _set by default.

Can I make ORM calls without hooks?

Due to Django's ORM design, database queries must be deferred using hooks. Otherwise, you will see a SynchronousOnlyOperation exception.

These SynchronousOnlyOperation exceptions may be removed in a future version of Django. However, it is best practice to always perform IO operations (such as ORM queries) via hooks to prevent performance issues.

Can I make a failed query try again?

Yes, a use_mutation can be re-performed by calling reset() on your use_mutation instance.

For example, take a look at reset_event below.

 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
26
27
28
29
30
31
32
from example.models import TodoItem
from reactpy import component, html
from reactpy_django.hooks import use_mutation


def add_item(text: str):
    TodoItem(text=text).save()


@component
def todo_list():
    item_mutation = use_mutation(add_item)

    def reset_event(event):
        item_mutation.reset()

    def submit_event(event):
        if event["key"] == "Enter":
            item_mutation(text=event["target"]["value"])

    if item_mutation.loading:
        mutation_status = html.h2("Adding...")
    elif item_mutation.error:
        mutation_status = html.button({"on_click": reset_event}, "Error: Try again!")
    else:
        mutation_status = html.h2("Mutation done.")

    return html.div(
        html.label("Add an item:"),
        html.input({"type": "text", "on_key_down": submit_event}),
        mutation_status,
    )
1
2
3
4
5
from django.db.models import CharField, Model


class TodoItem(Model):
    text: CharField = CharField(max_length=255)
Why does the example query function return TodoItem.objects.all()?

This design decision was based on Apollo's useQuery hook, but ultimately helps avoid Django's SynchronousOnlyOperation exceptions.

With the Model or QuerySet your function returns, this hook uses the default postprocessor to ensure that all deferred or lazy fields are executed.


Use Mutation

Modify data in the background, typically to create/update/delete data from the Django ORM.

Mutation functions can return False to manually prevent your refetch=... function from executing. All other returns are ignored.

Mutation functions can be sync or async.

 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
26
27
28
29
from example.models import TodoItem
from reactpy import component, html
from reactpy_django.hooks import use_mutation


async def add_item(text: str):
    await TodoItem(text=text).asave()


@component
def todo_list():
    item_mutation = use_mutation(add_item)

    def submit_event(event):
        if event["key"] == "Enter":
            item_mutation(text=event["target"]["value"])

    if item_mutation.loading:
        mutation_status = html.h2("Adding...")
    elif item_mutation.error:
        mutation_status = html.h2("Error when adding!")
    else:
        mutation_status = html.h2("Mutation done.")

    return html.div(
        html.label("Add an item:"),
        html.input({"type": "text", "on_key_down": submit_event}),
        mutation_status,
    )
1
2
3
4
5
from django.db.models import CharField, Model


class TodoItem(Model):
    text: CharField = CharField(max_length=255)
See Interface

Parameters

Name Type Description Default
mutation Callable[_Params, bool | None] A callable that performs Django ORM create, update, or delete functionality. If this function returns False, then your refetch function will not be used. N/A
refetch Callable[..., Any] | Sequence[Callable[..., Any]] | None A query function (the function you provide to your use_query hook) or a sequence of query functions that need a refetch if the mutation succeeds. This is useful for refreshing data after a mutation has been performed. None

Returns

Type Description
Mutation[_Params] An object containing loading/error states, a reset callable that will set loading/error states to defaults, and a execute callable that will run the query.
How can I provide arguments to my mutation function?

*args and **kwargs can be provided to your mutation function via mutation(...) parameters.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
from reactpy import component
from reactpy_django.hooks import use_mutation


def example_mutation(value: int, other_value: bool = False):
    ...


@component
def my_component():
    mutation = use_mutation(example_mutation)

    mutation(123, other_value=True)

    ...
How can I customize this hook's behavior?

This hook accepts a options: MutationOptions parameter that can be used to customize behavior.

Below are the settings that can be modified via these MutationOptions.


thread_sensitive

Whether to run your synchronous mutation function in thread-sensitive mode. Thread-sensitive mode is turned on by default due to Django ORM limitations. See Django's sync_to_async docs docs for more information.

This setting only applies to sync query functions, and will be ignored for async functions.

 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
26
27
28
29
30
31
32
from reactpy import component, html
from reactpy_django.hooks import use_mutation
from reactpy_django.types import MutationOptions


def execute_thread_safe_mutation(text):
    """This is an example mutation function that does some thread-safe operation."""
    pass


@component
def my_component():
    item_mutation = use_mutation(
        MutationOptions(thread_sensitive=False),
        execute_thread_safe_mutation,
    )

    def submit_event(event):
        if event["key"] == "Enter":
            item_mutation(text=event["target"]["value"])

    if item_mutation.loading or item_mutation.error:
        mutation_status = html.h2("Doing something...")
    elif item_mutation.error:
        mutation_status = html.h2("Error!")
    else:
        mutation_status = html.h2("Done.")

    return html.div(
        html.input({"type": "text", "on_key_down": submit_event}),
        mutation_status,
    )
Can I make ORM calls without hooks?

Due to Django's ORM design, database queries must be deferred using hooks. Otherwise, you will see a SynchronousOnlyOperation exception.

These SynchronousOnlyOperation exceptions may be removed in a future version of Django. However, it is best practice to always perform IO operations (such as ORM queries) via hooks to prevent performance issues.

Can I make a failed mutation try again?

Yes, a use_mutation can be re-performed by calling reset() on your use_mutation instance.

For example, take a look at reset_event below.

 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
26
27
28
29
30
31
32
from example.models import TodoItem
from reactpy import component, html
from reactpy_django.hooks import use_mutation


def add_item(text: str):
    TodoItem(text=text).save()


@component
def todo_list():
    item_mutation = use_mutation(add_item)

    def reset_event(event):
        item_mutation.reset()

    def submit_event(event):
        if event["key"] == "Enter":
            item_mutation(text=event["target"]["value"])

    if item_mutation.loading:
        mutation_status = html.h2("Adding...")
    elif item_mutation.error:
        mutation_status = html.button({"on_click": reset_event}, "Error: Try again!")
    else:
        mutation_status = html.h2("Mutation done.")

    return html.div(
        html.label("Add an item:"),
        html.input({"type": "text", "on_key_down": submit_event}),
        mutation_status,
    )
1
2
3
4
5
from django.db.models import CharField, Model


class TodoItem(Model):
    text: CharField = CharField(max_length=255)
Can use_mutation trigger a refetch of use_query?

Yes, use_mutation can queue a refetch of a use_query via the refetch=... argument.

The example below is a merge of the use_query and use_mutation examples above with the addition of a use_mutation(refetch=...) argument.

Please note that refetch will cause all use_query hooks that use get_items in the current component tree will be refetched.

 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
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
from example.models import TodoItem
from reactpy import component, html
from reactpy_django.hooks import use_mutation, use_query


def get_items():
    return TodoItem.objects.all()


def add_item(text: str):
    TodoItem(text=text).save()


@component
def todo_list():
    item_query = use_query(get_items)
    item_mutation = use_mutation(add_item, refetch=get_items)

    def submit_event(event):
        if event["key"] == "Enter":
            item_mutation(text=event["target"]["value"])

    # Handle all possible query states
    if item_query.loading:
        rendered_items = html.h2("Loading...")
    elif item_query.error or not item_query.data:
        rendered_items = html.h2("Error when loading!")
    else:
        rendered_items = html.ul(html.li(item, key=item) for item in item_query.data)

    # Handle all possible mutation states
    if item_mutation.loading:
        mutation_status = html.h2("Adding...")
    elif item_mutation.error:
        mutation_status = html.h2("Error when adding!")
    else:
        mutation_status = html.h2("Mutation done.")

    return html.div(
        html.label("Add an item:"),
        html.input({"type": "text", "on_key_down": submit_event}),
        mutation_status,
        rendered_items,
    )
1
2
3
4
5
from django.db.models import CharField, Model


class TodoItem(Model):
    text: CharField = CharField(max_length=255)

Use User Data

Store or retrieve a dict containing user data specific to the connection's User.

This hook is useful for storing user-specific data, such as preferences, settings, or any generic key-value pairs.

User data saved with this hook is stored within the REACTPY_DATABASE.

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


@component
def my_component():
    query, mutation = use_user_data()

    def on_submit(event):
        if event["key"] == "Enter" and query.data:
            new_key = str(len(query.data))
            mutation({**query.data, new_key: event["target"]["value"]})

    return html.div(
        html.div(f"Data: {query.data}"),
        html.div(f"Loading: {query.loading | mutation.loading}"),
        html.div(f"Error(s): {query.error} {mutation.error}"),
        html.input({"on_key_press": on_submit}),
    )
See Interface

Parameters

Name Type Description Default
default_data None | dict[str, Callable[[], Any] | Callable[[], Awaitable[Any]] | Any] A dictionary containing {key: default_value} pairs. For computationally intensive defaults, your default_value can be sync or async functions that return the value to set. None
save_default_data bool If True, default_data values will automatically be stored within the database if they do not exist. False

Returns

Type Description
UserData A NamedTuple containing a Query and Mutation objects used to access/modify user data. Read the use_query and use_mutation docs for more details.
How do I set default values?

You can configure default user data via the default_data parameter.

This parameter accepts a dictionary containing a {key: default_value} pairs. For computationally intensive defaults, your default_value can be sync or async functions that return the value to set.

 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
from reactpy_django.hooks import use_user_data


@component
def my_component():
    user_data = use_user_data(
        default_data={
            "basic_example": "123",
            "computed_example_sync": sync_default,
            "computed_example_async": async_default,
        }
    )

    return html.div(
        html.div(f"Data: {user_data.query.data}"),
    )


def sync_default():
    return ...


async def async_default():
    return ...

Communication Hooks


Use Channel Layer

Subscribe to a Django Channels layer to send/receive messages.

Layers are a multiprocessing-safe communication system that allows you to send/receive messages between different parts of your application.

This is often used to create chat systems, synchronize data between components, or signal re-renders from outside your components.

 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
26
27
28
from reactpy import component, hooks, html
from reactpy_django.hooks import use_channel_layer


@component
def my_sender_component():
    sender = use_channel_layer("my-channel-name")

    async def submit_event(event):
        if event["key"] == "Enter":
            await sender({"text": event["target"]["value"]})

    return html.div(
        "Message Sender: ",
        html.input({"type": "text", "onKeyDown": submit_event}),
    )


@component
def my_receiver_component():
    message, set_message = hooks.use_state("")

    async def receive_event(message):
        set_message(message["text"])

    use_channel_layer("my-channel-name", receiver=receive_event)

    return html.div(f"Message Receiver: {message}")
See Interface

Parameters

Name Type Description Default
name str | None The name of the channel to subscribe to. If you define a group_name, you can keep name undefined to auto-generate a unique name. None
group_name str | None If configured, any messages sent within this hook will be broadcasted to all channels in this group. None
group_add bool If True, the channel will automatically be added to the group when the component mounts. True
group_discard bool If True, the channel will automatically be removed from the group when the component dismounts. True
receiver AsyncMessageReceiver | None An async function that receives a message: dict from a channel. If more than one receiver waits on the same channel name, a random receiver will get the result. None
layer str The channel layer to use. This layer must be defined in settings.py:CHANNEL_LAYERS. 'default'

Returns

Type Description
AsyncMessageSender An async callable that can send a message: dict.
Extra Django configuration required

In order to use this hook, you will need to configure Django to enable channel layers.

The Django Channels documentation has information on what steps you need to take.

In summary, you will need to:

  1. Install redis on your machine.

  2. Run the following command to install channels-redis in your Python environment.

    pip install channels-redis
    
  3. Configure your settings.py to use RedisChannelLayer as your layer backend.

    CHANNEL_LAYERS = {
        "default": {
            "BACKEND": "channels_redis.core.RedisChannelLayer",
            "CONFIG": {
                "hosts": [("127.0.0.1", 6379)],
            },
        },
    }
    
How do I broadcast a message to multiple components?

If more than one receiver waits on the same channel, a random one will get the result.

To get around this, you can define a group_name to broadcast messages to all channels within a specific group. If you do not define a channel name while using groups, ReactPy will automatically generate a unique channel name for you.

In the example below, all messages sent by the sender component will be received by all receiver components that exist (across every active client browser).

 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
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
from reactpy import component, hooks, html
from reactpy_django.hooks import use_channel_layer


@component
def my_sender_component():
    sender = use_channel_layer(group_name="my-group-name")

    async def submit_event(event):
        if event["key"] == "Enter":
            await sender({"text": event["target"]["value"]})

    return html.div(
        "Message Sender: ",
        html.input({"type": "text", "onKeyDown": submit_event}),
    )


@component
def my_receiver_component_1():
    message, set_message = hooks.use_state("")

    async def receive_event(message):
        set_message(message["text"])

    use_channel_layer(group_name="my-group-name", receiver=receive_event)

    return html.div(f"Message Receiver 1: {message}")


@component
def my_receiver_component_2():
    message, set_message = hooks.use_state("")

    async def receive_event(message):
        set_message(message["text"])

    use_channel_layer(group_name="my-group-name", receiver=receive_event)

    return html.div(f"Message Receiver 2: {message}")
How do I signal a re-render from something that isn't a component?

There are occasions where you may want to signal a re-render from something that isn't a component, such as a Django model signal.

In these cases, you can use the use_channel_layer hook to receive a signal within your component, and then use the get_channel_layer().send(...) to send the signal.

In the example below, the sender will send a signal every time ExampleModel is saved. Then, when the receiver component gets this signal, it explicitly calls set_message(...) to trigger a re-render.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
from asgiref.sync import async_to_sync
from channels.layers import get_channel_layer
from django.db.models import Model
from django.db.models.signals import pre_save
from django.dispatch import receiver


class ExampleModel(Model): ...


@receiver(pre_save, sender=ExampleModel)
def my_sender_signal(sender, instance, **kwargs):
    layer = get_channel_layer()

    # Example of sending a message to a channel
    async_to_sync(layer.send)("my-channel-name", {"text": "Hello World!"})

    # Example of sending a message to a group channel
    async_to_sync(layer.group_send)("my-group-name", {"text": "Hello World!"})
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
from reactpy import component, hooks, html
from reactpy_django.hooks import use_channel_layer


@component
def my_receiver_component():
    message, set_message = hooks.use_state("")

    async def receive_event(message):
        set_message(message["text"])

    use_channel_layer("my-channel-name", receiver=receive_event)

    return html.div(f"Message Receiver: {message}")

Connection Hooks


Use Connection

Returns the active connection, which is either a Django WebSocket or a HTTP Request.

1
2
3
4
5
6
7
8
9
from reactpy import component, html
from reactpy_django.hooks import use_connection


@component
def my_component():
    connection = use_connection()

    return html.div(str(connection))
See Interface

Parameters

None

Returns

Type Description
Connection An object that contains a carrier (WebSocket or HttpRequest), scope, and location.

Use Scope

Shortcut that returns the WebSocket or HTTP connection's scope.

1
2
3
4
5
6
7
8
9
from reactpy import component, html
from reactpy_django.hooks import use_scope


@component
def my_component():
    scope = use_scope()

    return html.div(str(scope))
See Interface

Parameters

None

Returns

Type Description
MutableMapping[str, Any] The connection's scope.

Use Location

Shortcut that returns the browser's current Location.

1
2
3
4
5
6
7
8
9
from reactpy import component, html
from reactpy_django.hooks import use_location


@component
def my_component():
    location = use_location()

    return html.div(location.pathname + location.search)
See Interface

Parameters

None

Returns

Type Description
Location An object containing the current URL's pathname and search query.

Use Origin

Shortcut that returns the WebSocket or HTTP connection's origin.

You can expect this hook to provide strings such as http://example.com.

1
2
3
4
5
6
7
8
9
from reactpy import component, html
from reactpy_django.hooks import use_origin


@component
def my_component():
    origin = use_origin()

    return html.div(origin or "No origin")
See Interface

Parameters

None

Returns

Type Description
str | None A string containing the browser's current origin, obtained from WebSocket or HTTP headers (if available).

Use Root ID

Shortcut that returns the root component's id from the WebSocket or HTTP connection.

The root ID is currently a randomly generated uuid4 (unique across all root component).

This is useful when used in combination with use_channel_layer to send messages to a specific component instance, and/or retain a backlog of messages in case that component is disconnected via use_channel_layer( ... , group_discard=False).

1
2
3
4
5
6
7
8
9
from reactpy import component, html
from reactpy_django.hooks import use_root_id


@component
def my_component():
    root_id = use_root_id()

    return html.div(f"Root ID: {root_id}")
See Interface
1
2
3
4
5
6
7
8
9
<font size="4">**Parameters**</font>

`#!python None`

<font size="4">**Returns**</font>

| Type | Description |
| --- | --- |
| `#!python str` | A string containing the root component's `#!python id`. |

Use User

Shortcut that returns the WebSocket or HTTP connection's User.

1
2
3
4
5
6
7
8
9
from reactpy import component, html
from reactpy_django.hooks import use_user


@component
def my_component():
    user = use_user()

    return html.div(user.username)
See Interface

Parameters

None

Returns

Type Description
AbstractUser A Django User, which can also be an AnonymousUser.

Last update: February 21, 2024
Authors: Mark Bakhit