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.
Use Query¶
This hook is used read data from the Django ORM.
The query function you provide must return either a Model or QuerySet.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | |
1 2 3 4 5 | |
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 | |
Why does get_items in the example return TodoItem.objects.all()?
This was a technical design decision to based on Apollo's useQuery hook, but ultimately helps avoid Django's SynchronousOnlyOperation exceptions.
The use_query hook ensures the provided Model or QuerySet executes all deferred/lazy queries safely prior to reaching your components.
How can I use QueryOptions to customize fetching behavior?
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 | |
postprocessor
By default, automatic recursive fetching of ManyToMany or ForeignKey fields is enabled within the default QueryOptions.postprocessor. This is needed to prevent SynchronousOnlyOperation exceptions when accessing these fields within your ReactPy components.
However, if you...
- Want to use this hook to defer IO intensive tasks to be computed in the background
- Want to to utilize
use_querywith 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 | |
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 | |
postprocessor_kwargs
By default, automatic recursive fetching of ManyToMany or ForeignKey fields is enabled within the default QueryOptions.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 | |
Note: In Django's ORM design, the field name to access foreign keys is postfixed with _set by default.
Can I define async query functions?
Async functions are supported by use_query. You can use them in the same way as a sync query function.
However, be mindful of Django async ORM restrictions.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | |
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 resolved in a future version of Django containing an asynchronous ORM. However, it is best practice to always perform ORM calls in the background via hooks.
Use Mutation¶
This hook is used to create, update, or delete Django ORM objects.
The mutation function you provide should have no return value.
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 | |
1 2 3 4 5 | |
See Interface
Parameters
| Name | Type | Description | Default |
|---|---|---|---|
mutate | 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 (used by the use_query hook) or a sequence of query functions that will be called if the mutation succeeds. This is useful for refetching 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 #!python mutation.execute` parameters.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | |
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 any use_query hooks that use get_items will be refetched upon a successful mutation.
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 | |
1 2 3 4 5 | |
Can I make a failed use_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 | |
1 2 3 4 5 | |
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 resolved in a future version of Django containing an asynchronous ORM. However, it is best practice to always perform ORM calls in the background via hooks.
Use Connection¶
This hook is used to fetch the Django Channels WebSocket.
1 2 3 4 5 6 7 8 | |
See Interface
Parameters
None
Returns
| Type | Description |
|---|---|
Connection | The component's WebSocket. |
Use Scope¶
This is a shortcut that returns the WebSocket's scope.
1 2 3 4 5 6 7 8 | |
See Interface
Parameters
None
Returns
| Type | Description |
|---|---|
MutableMapping[str, Any] | The WebSocket's scope. |
Use Location¶
This is a shortcut that returns the WebSocket's path.
You can expect this hook to provide strings such as /reactpy/my_path.
1 2 3 4 5 6 7 8 | |
See Interface
Parameters
None
Returns
| Type | Description |
|---|---|
Location | An object containing the current URL's pathname and search query. |
This hook's behavior will be changed in a future update
This hook will be updated to return the browser's currently active HTTP path. This change will come in alongside ReactPy URL routing support.
Check out reactive-python/reactpy-django#147 for more information.
Use Origin¶
This is a shortcut that returns the WebSocket's origin.
You can expect this hook to provide strings such as http://example.com.
1 2 3 4 5 6 7 8 | |
See Interface
Parameters
None
Returns
| Type | Description |
|---|---|
str | None | A string containing the browser's current origin, obtained from WebSocket headers (if available). |