Skip to content

reactpy v2.0.0b8

Pre-release
Pre-release

Choose a tag to compare

@Archmonger Archmonger released this 05 Feb 17:44
· 3 commits to main since this release
aa307e1

New changes compared to v2.0.0b7

  • Fix scenario where @component decorated functions would fail to render as a child of a Client Side Component (CSR).
  • Fix use_async_effect cleanup functions not executing when dependencies have changed

Summary

Welcome to the latest beta release of ReactPy v2, which brings ReactPy Standalone and ReactPy Middleware!

Here is a quick demo of the new ReactPy Standalone:

# FILENAME: example.py
# Install dependencies: pip install reactpy[asgi]==2.0.0b8 uvicorn[standard]
from reactpy import component, html
from reactpy.executors.asgi import ReactPy

@component
def ExampleComponent():
    return html.div("Hello World")

app = ReactPy(ExampleComponent)

# Now you can run `uvicorn example:app --reload` to start ReactPy!

Here is a quick demo of the new ReactPy Middleware (using FastAPI for demonstration purposes):

# FILENAME: example.py
# Install dependencies: pip install reactpy[asgi, jinja]==2.0.0b8 uvicorn[standard] starlette
from fastapi import FastAPI, Request
from fastapi.responses import HTMLResponse
from fastapi.staticfiles import StaticFiles
from fastapi.templating import Jinja2Templates

from reactpy import component, html
from reactpy.executors.asgi import ReactPyMiddleware

# Follow your framework's documentation on installing Jinja extensions. You will need to install
# ReactPy's Jinja extension to use ReactPy's `{% component "example.path" %}` template tag.
fastapi_app = FastAPI()
fastapi_app.mount("/static", StaticFiles(directory="static"), name="static")
templates = Jinja2Templates(directory="templates", extensions=["reactpy.templatetags.ReactPyJinja"])

@fastapi_app.get("/", response_class=HTMLResponse)
async def homepage(request: Request):
    # Note: Use ReactPy's template tag in any Jinja template to render a component.
    return templates.TemplateResponse(request, "index.html")

@component # Note: Component is declared in this file to simplify the demo.
def HelloWorld():
    return html.div("Hello, World!")

# Register components with ReactPy to allow them to be used in your templates
app = ReactPyMiddleware(fastapi_app, root_components=["example.HelloWorld"])

# Now you can run `uvicorn example:app --reload` to start ReactPy!
<!-- FILENAME: index.html -->
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Example Webpage</title>
</head>
<body>
    <h1>Welcome to the Example Webpage</h1>
    {% component "example.HelloWorld" %}
</body>
</html>

Changelog

Added

  • Added support for Python 3.12, 3.13, and 3.14.
  • Added type hints to reactpy.html attributes.
  • Added support for nested components in web modules
  • Added support for inline JavaScript as event handlers or other attributes that expect a callable via reactpy.types.InlineJavaScript
  • Event functions can now call event.preventDefault() and event.stopPropagation() methods directly on the event data object, rather than using the @event decorator.
  • Event data now supports accessing properties via dot notation (ex. event.target.value).
  • Added reactpy.types.Event to provide type hints for the standard data function argument (for example def on_click(event: Event): ...).
  • Added asgi and jinja installation extras (for example pip install reactpy[asgi, jinja]).
  • Added reactpy.executors.asgi.ReactPy that can be used to run ReactPy in standalone mode via ASGI.
  • Added reactpy.executors.asgi.ReactPyCsr that can be used to run ReactPy in standalone mode via ASGI, but rendered entirely client-sided.
  • Added reactpy.executors.asgi.ReactPyMiddleware that can be used to utilize ReactPy within any ASGI compatible framework.
  • Added reactpy.templatetags.ReactPyJinja that can be used alongside ReactPyMiddleware to embed several ReactPy components into your existing application. This includes the following template tags: {% component %}, {% pyscript_component %}, and {% pyscript_setup %}.
  • Added reactpy.pyscript_component that can be used to embed ReactPy components into your existing application.
  • Added reactpy.use_async_effect hook.
  • Added reactpy.Vdom primitive interface for creating VDOM dictionaries.
  • Added reactpy.reactjs.component_from_file to import ReactJS components from a file.
  • Added reactpy.reactjs.component_from_url to import ReactJS components from a URL.
  • Added reactpy.reactjs.component_from_string to import ReactJS components from a string.
  • Added reactpy.reactjs.component_from_npm to import ReactJS components from NPM.
  • Added reactpy.h as a shorthand alias for reactpy.html.

Changed

  • The key attribute is now stored within attributes in the VDOM spec.
  • Substitute client-side usage of react with preact.
  • Script elements no longer support behaving like effects. They now strictly behave like plain HTML scripts.
  • The reactpy.html module has been modified to allow for auto-creation of any HTML nodes. For example, you can create a <data-table> element by calling html.data_table().
  • Change set_state comparison method to check equality with == more consistently.
  • Add support for rendering @component children within vdom_to_html.
  • Renamed the use_location hook's search attribute to query_string.
  • Renamed the use_location hook's pathname attribute to path.
  • Renamed reactpy.config.REACTPY_DEBUG_MODE to reactpy.config.REACTPY_DEBUG.
  • ReactPy no longer auto-converts snake_case props to camelCase. It is now the responsibility of the user to ensure that props are in the correct format.
  • Rewrite the event-to-object package to be more robust at handling properties on events.
  • Custom JS components will now automatically assume you are using ReactJS in the absence of a bind function.
  • Refactor layout rendering logic to improve readability and maintainability.
  • @reactpy/client now exports React and ReactDOM.
  • reactpy.html will now automatically flatten lists recursively (ex. reactpy.html(["child1", ["child2"]]))
  • reactpy.utils.reactpy_to_string will now retain the user's original casing for data-* and aria-* attributes.
  • reactpy.utils.string_to_reactpy has been upgraded to handle more complex scenarios without causing ReactJS rendering errors.
  • reactpy.core.vdom._CustomVdomDictConstructor has been moved to reactpy.types.CustomVdomConstructor.
  • reactpy.core.vdom._EllipsisRepr has been moved to reactpy.types.EllipsisRepr.
  • reactpy.types.VdomDictConstructor has been renamed to reactpy.types.VdomConstructor.
  • REACTPY_ASYNC_RENDERING can now de-duplicate and cascade renders where necessary.
  • REACTPY_ASYNC_RENDERING is now defaulted to True for up to 40x performance improvements in environments with high concurrency.

Deprecated

  • reactpy.web.module_from_file is deprecated. Use reactpy.reactjs.component_from_file instead.
  • reactpy.web.module_from_url is deprecated. Use reactpy.reactjs.component_from_url instead.
  • reactpy.web.module_from_string is deprecated. Use reactpy.reactjs.component_from_string instead.
  • reactpy.web.export is deprecated. Use reactpy.reactjs.component_from_* instead.
  • reactpy.web.* is deprecated. Use reactpy.reactjs.* instead.

Removed

  • Removed support for Python 3.9 and 3.10.
  • Removed the ability to import reactpy.html.* elements directly. You must now call html.* to access the elements.
  • Removed backend specific installation extras (such as pip install reactpy[starlette]).
  • Removed support for async functions within reactpy.use_effect hook. Use reactpy.use_async_effect instead.
  • Removed deprecated function module_from_template.
  • Removed deprecated exception type reactpy.core.serve.Stop.
  • Removed deprecated component reactpy.widgets.hotswap.
  • Removed reactpy.sample module.
  • Removed reactpy.svg module. Contents previously within reactpy.svg.* can now be accessed via reactpy.html.svg.*.
  • Removed reactpy.html._ function. Use reactpy.html(...) or reactpy.html.fragment(...) instead.
  • Removed reactpy.run. See the documentation for the new method to run ReactPy applications.
  • Removed reactpy.backend.*. See the documentation for the new method to run ReactPy applications.
  • Removed reactpy.core.types module. Use reactpy.types instead.
  • Removed reactpy.utils.html_to_vdom. Use reactpy.utils.string_to_reactpy instead.
  • Removed reactpy.utils.vdom_to_html. Use reactpy.utils.reactpy_to_string instead.
  • Removed reactpy.vdom. Use reactpy.Vdom instead.
  • Removed reactpy.core.make_vdom_constructor. Use reactpy.Vdom instead.
  • Removed reactpy.core.custom_vdom_constructor. Use reactpy.Vdom instead.
  • Removed reactpy.Layout top-level re-export. Use reactpy.core.layout.Layout instead.
  • Removed reactpy.types.LayoutType. Use reactpy.types.BaseLayout instead.
  • Removed reactpy.types.ContextProviderType. Use reactpy.types.ContextProvider instead.
  • Removed reactpy.core.hooks._ContextProvider. Use reactpy.types.ContextProvider instead.
  • Removed reactpy.web.utils. Use reactpy.reactjs.utils instead.

Fixed

  • Fixed a bug where script elements would not render to the DOM as plain text.
  • Fixed a bug where the key property provided within server-side ReactPy code was failing to propagate to the front-end JavaScript components.
  • Fixed a bug where RuntimeError("Hook stack is in an invalid state") errors could be generated when using a webserver that reuses threads.
  • Allow for ReactPy and ReactJS components to be arbitrarily inserted onto the page with any possible hierarchy.