Skip to content

Latest commit

 

History

History
1182 lines (813 loc) · 40.2 KB

changelog.rst

File metadata and controls

1182 lines (813 loc) · 40.2 KB

Changelog

Note

All notable changes to this project will be recorded in this document. The style of which is based on Keep a Changelog. The versioning scheme for the project adheres to Semantic Versioning. For more info, see the :ref:`Contributor Guide <Creating a Changelog Entry>`.

Unreleased

Nothing (yet)!

v1.1.0

Fixed

  • :pull:`1118` - module_from_template is broken with a recent release of requests
  • :pull:`1131` - module_from_template did not work when using Flask backend
  • :pull:`1200` - Fixed UnicodeDecodeError when using reactpy.web.export
  • :pull:`1224` - Fixes needless unmounting of JavaScript components during each ReactPy render.
  • :pull:`1126` - Fixed missing event["target"]["checked"] on checkbox inputs
  • :pull:`1191` - Fixed missing static files on sdist Python distribution

Added

  • :pull:`1165` - Allow concurrently rendering discrete component trees - enable this experimental feature by setting REACTPY_ASYNC_RENDERING=true. This improves the overall responsiveness of your app in situations where larger renders would otherwise block smaller renders from executing.

Changed

  • :pull:`1171` - Previously None, when present in an HTML element, would render as the string "None". Now None will not render at all. This is consistent with how None is handled when returned from components. It also makes it easier to conditionally render elements. For example, previously you would have needed to use a fragment to conditionally render an element by writing something if condition else html._(). Now you can simply write something if condition else None.
  • :pull:`1210` - Move hooks from reactpy.backend.hooks into reactpy.core.hooks.

Deprecated

  • :pull:`1171` - The Stop exception. Recent releases of anyio have made this exception difficult to use since it now raises an ExceptionGroup. This exception was primarily used for internal testing purposes and so is now deprecated.
  • :pull:`1210` - Deprecate reactpy.backend.hooks since the hooks have been moved into reactpy.core.hooks.

v1.0.2

Fixed

v1.0.1

Changed

  • :pull:`1050` - Warn and attempt to fix missing mime types, which can result in reactpy.run not working as expected.
  • :pull:`1051` - Rename reactpy.backend.BackendImplementation to reactpy.backend.BackendType
  • :pull:`1051` - Allow reactpy.run to fail in more predictable ways

Fixed

v1.0.0

:octicon:`milestone` released on 2023-03-14

No changes.

v1.0.0-a6

:octicon:`milestone` released on 2023-02-23

Fixed

v1.0.0-a5

:octicon:`milestone` released on 2023-02-21

Fixed

  • :pull:`934` - minor issues with camelCase rewrite CLI utility

v1.0.0-a4

:octicon:`milestone` released on 2023-02-21

Changed

Deprecated

  • :pull:`919` - Declaration of keys via keyword arguments in standard elements. A script has been added to automatically convert old usages where possible.

v1.0.0-a3

:octicon:`milestone` released on 2023-02-02

Fixed

  • :pull:`908` - minor type hint issue with VdomDictConstructor

Removed

v1.0.0-a2

:octicon:`milestone` released on 2023-01-31

Reverted

Fixed

  • :issue:`896` - Stale event handlers after disconnect/reconnect cycle
  • :issue:`898` - Fixed CLI not registered as entry point

v1.0.0-a1

:octicon:`milestone` released on 2023-01-28

Changed

  • :pull:`841` - Revamped element constructor interface. Now instead of passing a dictionary of attributes to element constructors, attributes are declared using keyword arguments. For example, instead of writing:

    html.div({"className": "some-class"}, "some", "text")
    

    You now should write:

    html.div("some", "text", class_name="some-class")
    

    Note

    All attributes are written using snake_case.

    In conjunction, with these changes, ReactPy now supplies a command line utility that makes a "best effort" attempt to automatically convert code to the new API. Usage of this utility is as follows:

    reactpy update-html-usages [PATHS]

    Where [PATHS] is any number of directories or files that should be rewritten.

    Warning

    After running this utility, code comments and formatting may have been altered. It's recommended that you run a code formatting tool like Black and manually review and replace any comments that may have been moved.

Fixed

  • :issue:`755` - unification of component and VDOM constructor interfaces. See above.

v0.44.0

:octicon:`milestone` released on 2023-01-27

Deprecated

  • :pull:`876` - reactpy.widgets.hotswap. The function has no clear uses outside of some internal applications. For this reason it has been deprecated.

Removed

  • :pull:`886` - Ability to access element value from events via event['value'] key. Instead element value should be accessed via event['target']['value']. Originally deprecated in :ref:`v0.34.0`.
  • :pull:`886` - old misspelled option reactpy.config.REACTPY_WED_MODULES_DIR. Originally deprecated in :ref:`v0.36.1`.

v0.43.0

:octicon:`milestone` released on 2023-01-09

Deprecated

  • :pull:`870` - ComponentType.should_render(). This method was implemented based on reading the React/Preact source code. As it turns out though it seems like it's mostly a vestige from the fact that both these libraries still support class-based components. The ability for components to not render also caused several bugs.

Fixed

  • :issue:`846` - Nested context does no update value if outer context should not render.
  • :issue:`847` - Detached model state on render of context consumer if unmounted and context value does not change.

v0.42.0

:octicon:`milestone` released on 2022-12-02

Added

  • :pull:`835` - Ability to customize the <head> element of ReactPy's built-in client.
  • :pull:`835` - vdom_to_html utility function.
  • :pull:`843` - Ability to subscribe to changes that are made to mutable options.
  • :pull:`832` - del_html_head_body_transform to remove <html>, <head>, and <body> while preserving children.
  • :pull:`699` - Support for form element serialization

Fixed

  • :issue:`582` - REACTPY_DEBUG_MODE is now mutable and can be changed at runtime
  • :pull:`832` - Fix html_to_vdom improperly removing <html>, <head>, and <body> nodes.

Removed

  • :pull:`832` - Removed reactpy.html.body as it is currently unusable due to technological limitations, and thus not needed.
  • :pull:`840` - remove REACTPY_FEATURE_INDEX_AS_DEFAULT_KEY option
  • :pull:`835` - serve_static_files option from backend configuration

Deprecated

v0.41.0

:octicon:`milestone` released on 2022-11-01

Changed

  • :pull:`823` - The hooks use_location and use_scope are no longer implementation specific and are now available as top-level imports. Instead of each backend defining these hooks, backends establish a ConnectionContext with this information.

  • :pull:`824` - ReactPy's built-in backend server now expose the following routes:

    • /_reactpy/assets/<file-path>
    • /_reactpy/stream/<path>
    • /_reactpy/modules/<file-path>
    • /<prefix>/<path>

    This should allow the browser to cache static resources. Even if your url_prefix is /_reactpy, your app should still work as expected. Though if you're using reactpy-router, ReactPy's server routes will always take priority.

  • :pull:`824` - Backend implementations now strip any URL prefix in the pathname for use_location.

  • :pull:`827` - use_state now returns a named tuple with value and set_value fields. This is convenient for adding type annotations if the initial state value is not the same as the values you might pass to the state setter. Where previously you might have to do something like:

    value: int | None = None
    value, set_value = use_state(value)
    

    Now you can annotate your state using the State class:

    state: State[int | None] = use_state(None)
    
    # access value and setter
    state.value
    state.set_value
    
    # can still destructure if you need to
    value, set_value = state
    

Added

  • :pull:`823` - There is a new use_connection hook which returns a Connection object. This Connection object contains a location and scope, along with a carrier which is unique to each backend implementation.

v0.40.2

:octicon:`milestone` released on 2022-09-13

Changed

  • :pull:`809` - Avoid the use of JSON patch for diffing models.

v0.40.1

:octicon:`milestone` released on 2022-09-11

Fixed

  • :issue:`806` - Child models after a component fail to render

v0.40.0 (yanked)

:octicon:`milestone` released on 2022-08-13

Fixed

  • :issue:`777` - Fix edge cases where html_to_vdom can fail to convert HTML
  • :issue:`789` - Conditionally rendered components cannot use contexts
  • :issue:`773` - Use strict equality check for text, numeric, and binary types in hooks
  • :issue:`801` - Accidental mutation of old model causes invalid JSON Patch

Changed

  • :pull:`123` - set default timeout on playwright page for testing
  • :pull:`787` - Track contexts in hooks as state
  • :pull:`787` - remove non-standard name argument from create_context

Added

v0.39.0

:octicon:`milestone` released on 2022-06-20

Fixed

  • :pull:`763` - No module named 'reactpy.server' from reactpy.run
  • :pull:`749` - Setting appropriate MIME type for web modules in sanic server implementation

Changed

  • :pull:`763` - renamed various:
    • reactpy.testing.server -> reactpy.testing.backend
    • ServerFixture -> BackendFixture
    • DisplayFixture.server -> DisplayFixture.backend
  • :pull:`765` - exports_default parameter is removed from module_from_template.

Added

  • :pull:`765` - ability to specify versions with module templates (e.g. module_from_template("react@^17.0.0", ...)).

v0.38.1

:octicon:`milestone` released on 2022-04-15

Fixed

v0.38.0

:octicon:`milestone` released on 2022-04-15

No changes.

v0.38.0-a4

:octicon:`milestone` released on 2022-04-15

Added

Changed

  • :pull:`733` - renamed assert_reactpy_logged testing util to assert_reactpy_did_log

v0.38.0-a3

:octicon:`milestone` released on 2022-04-15

Changed

v0.38.0-a2

:octicon:`milestone` released on 2022-04-14

Added

  • :pull:`721` - Implement use_location() hook. Navigating to any route below the root of the application will be reflected in the location.pathname. This operates in concert with how ReactPy's configured routes have changed. This will ultimately work towards resolving :issue:`569`.

Changed

  • :pull:`721` - The routes ReactPy configures on apps have changed

    prefix/_api/modules/*    web modules
    prefix/_api/stream       websocket endpoint
    prefix/*                 client react app
    

    This means that ReactPy's client app is available at any route below the configured url_prefix besides prefix/_api. The _api route will likely remain a route which is reserved by ReactPy. The route navigated to below the prefix will be shown in use_location.

  • :pull:`721` - ReactPy's client now uses Preact instead of React

  • :pull:`726` - Renamed reactpy.server to reactpy.backend. Other references to "server implementations" have been renamed to "backend implementations" throughout the documentation and code.

Removed

v0.38.0-a1

:octicon:`milestone` released on 2022-03-27

Changed

  • :pull:`703` - How ReactPy integrates with servers. reactpy.run no longer accepts an app instance to discourage use outside of testing. ReactPy's server implementations now provide configure() functions instead. reactpy.testing has been completely reworked in order to support async web drivers
  • :pull:`703` - PerClientStateServer has been functionally replaced by configure

Added

  • :issue:`669` - Access to underlying server requests via contexts

Removed

  • :issue:`669` - Removed reactpy.widgets.multiview since basic routing view use_scope is now possible as well as all SharedClientStateServer implementations.

Fixed

v0.37.2

:octicon:`milestone` released on 2022-03-27

Changed

  • :pull:`701` - The name of proto modules to types and added a top level reactpy.types module

Fixed

  • :pull:`716` - A typo caused ReactPy to use the insecure ws web-socket protocol on pages loaded with https instead of the secure wss protocol

v0.37.1

:octicon:`milestone` released on 2022-03-05

No changes.

v0.37.1-a2

:octicon:`milestone` released on 2022-03-02

Fixed:

v0.37.1-a1

:octicon:`milestone` released on 2022-02-28

Fixed:

  • :issue:`684` - onChange event for inputs missing key strokes

v0.37.0

:octicon:`milestone` released on 2022-02-27

Added:

Fixed:

  • :issue:`690` - React warning about set state in unmounted component
  • :pull:`688` - Missing reset of schedule_render_later flag

Releases below do not use the "Keep a Changelog" style guidelines.


v0.36.3

:octicon:`milestone` released on 2022-02-18

Misc bug fixes along with a minor improvement that allows components to return None to render nothing.

Closed Issues

  • All child states wiped upon any child key change - :issue:`652`
  • Allow NoneType returns within components - :issue:`538`

Merged Pull Requests

v0.36.2

:octicon:`milestone` released on 2022-02-02

Hot fix for newly introduced DeprecatedOption:

v0.36.1

:octicon:`milestone` released on 2022-02-02

Includes bug fixes and renames the configuration option REACTPY_WED_MODULES_DIR to REACTPY_WEB_MODULES_DIR with a corresponding deprecation warning.

Closed Issues

Merged Pull Requests

  • mark old state as None if unmounting - :pull:`641`
  • rename REACTPY_WED_MODULES_DIR to REACTPY_WEB_MODULES_DIR - :pull:`638`

v0.36.0

:octicon:`milestone` released on 2022-01-30

This release includes an important fix for errors produced after :pull:`623` was merged. In addition there is not a new http.script element which can behave similarly to a standard HTML <script> or, if no attributes are given, operate similarly to an effect. If no attributes are given, and when the script evaluates to a function, that function will be called the first time it is mounted and any time the content of the script is subsequently changed. If the function then returns another function, that returned function will be called when the script is removed from the view, or just before the content of the script changes.

Closed Issues

Pull Requests

  • make scripts behave more like normal html script element - :pull:`632`
  • Fix state mismatch during component update - :pull:`631`
  • implement script element - :pull:`617`

v0.35.4

:octicon:`milestone` released on 2022-01-27

Keys for elements at the root of a component were not being tracked. Thus key changes for elements at the root did not trigger unmounts.

Closed Issues

  • Change Key of Parent Element Does Not Unmount Children - :issue:`622`

Pull Requests

v0.35.3

:octicon:`milestone` released on 2022-01-27

As part of :pull:`614`, elements which changed type were not deeply unmounted. This behavior is probably undesirable though since the state for children of the element in question would persist (probably unexpectedly).

Pull Requests

v0.35.2

:octicon:`milestone` released on 2022-01-26

This release includes several bug fixes. The most significant of which is the ability to change the type of an element in the try (i.e. to and from being a component) without getting an error. Originally the errors were introduced because it was though changing element type would not be desirable. This was not the case though - swapping types turns out to be quite common and useful.

Closed Issues

  • Allow Children with the Same Key to Vary in Type - :issue:`613`
  • Client Always Looks for Server at "/" - :issue:`611`
  • Web modules get double file extensions with v0.35.x - :issue:`605`

Pull Requests

v0.35.1

:octicon:`milestone` released on 2022-01-18

Re-add accidentally deleted py.typed file to distribution. See PEP-561 for info on this marker file.

v0.35.0

:octicon:`milestone` released on 2022-01-18

The highlight of this release is that the default :ref:`"key" <Organizing Items With Keys>` of all elements will be their index amongst their neighbors. Previously this behavior could be engaged by setting REACTPY_FEATURE_INDEX_AS_DEFAULT_KEY=1 when running ReactPy. In this release though, you will need to explicitly turn off this feature (i.e. =0) to return to the old behavior. With this change, some may notice additional error logs which warn that:

Key not specified for child in list ...

This is saying is that an element or component which was created in a list does not have a unique key. For more information on how to mitigate this warning refer to the docs on :ref:`Organizing Items With Keys`.

Closed Issues

Pull Requests

v0.34.0

:octicon:`milestone` released on 2021-12-16

This release contains a variety of minor fixes and improvements which came out of rewriting the documentation. The most significant of these changes is the remove of target element attributes from the top-level of event data dictionaries. For example, instead of being able to find the value of an input at event["value"] it will instead be found at event["target"]["value"]. For a short period we will issue a :class:`DeprecationWarning` when target attributes are requested at the top-level of the event dictionary. As part of this change we also add event["currentTarget"] and event["relatedTarget"] keys to the event dictionary as well as a event[some_target]["boundingClientRect"] where some_target may be "target", "currentTarget" or "relatedTarget".

Closed Issues

Pull Requests

v0.33.3

:octicon:`milestone` released on 2021-10-08

Contains a small number of bug fixes and improvements. The most significant change is the addition of a warning stating that REACTPY_FEATURE_INDEX_AS_DEFAULT_KEY=1 will become the default in a future release. Beyond that, a lesser improvement makes it possible to use the default export from a Javascript module when calling module_from_template by specifying exports_default=True as a parameter. A

Closed Issues

  • Memory leak in SharedClientStateServer - :issue:`511`
  • Cannot use default export in react template - :issue:`502`
  • Add warning that element index will be used as the default key in a future release - :issue:`428`

Pull Requests

v0.33.2

:octicon:`milestone` released on 2021-09-05

A release to fix a memory leak caused by event handlers that were not being removed when components updated.

Closed Issues

  • Non-root component event handlers cause memory leaks - :issue:`510`

v0.33.1

:octicon:`milestone` released on 2021-09-02

A hot fix for a regression introduced in 0.33.0 where the root element of the layout could not be updated. See :issue:`498` for more info. A regression test for this will be introduced in a future release.

Pull Requests

v0.33.0

:octicon:`milestone` released on 2021-09-02

The most significant fix in this release is for a regression which manifested in :issue:`480`, :issue:`489`, and :issue:`451` which resulted from an issue in the way JSON patches were being applied client-side. This was ultimately resolved by :pull:`490`. While it's difficult to test this without a more thorough Javascript suite, we added a test that should hopefully catch this in the future by proxy.

The most important breaking change, is yet another which modifies the Custom Javascript Component interface. We now add a create() function to the bind() interface that allows ReactPy's client to recursively create components from that (and only that) import source. Prior to this, the interface was given unrendered models for child elements. The imported module was then responsible for rendering them. This placed a large burden on the author to understand how to handle these unrendered child models. In addition, in the React template used by module_from_template we needed to import a version of @reactpy/client from the CDN - this had already caused some issues where the template required a version of @reactpy/client in the which had not been released yet.

Closed Issues

Pull Requests

v0.32.0

:octicon:`milestone` released on 2021-08-20

In addition to a variety of bug fixes and other minor improvements, there's a breaking change to the custom component interface - instead of exporting multiple functions that render custom components, we simply expect a single bind() function. binding function then must return an object with a render() and unmount() function. This change was made in order to better support the rendering of child models. See :ref:`Custom JavaScript Components` for details on the new interface.

Closed Issues

  • Docs broken on Firefox - :issue:`469`
  • URL resolution for web modules does not consider urls starting with / - :issue:`460`
  • Query params in package name for module_from_template not stripped - :issue:`455`
  • Make docs section margins larger - :issue:`450`
  • Search broken in docs - :issue:`443`
  • Move src/reactpy/client out of Python package - :issue:`429`
  • Use composition instead of classes async with Layout and LifeCycleHook - :issue:`412`
  • Remove Python language extension - :issue:`282`
  • Add keys to models so React doesn't complain of child arrays requiring them - :issue:`255`
  • Fix binder link in docs - :issue:`231`

Pull Requests

v0.31.0

:octicon:`milestone` released on 2021-07-14

The :class:`~reactpy.core.layout.Layout` is now a prototype, and Layout.update is no longer a public API. This is combined with a much more significant refactor of the underlying rendering logic.

The biggest issue that has been resolved relates to the relationship between :class:`~reactpy.core.hooks.LifeCycleHook` and Layout. Previously, the LifeCycleHook accepted a layout instance in its constructor and called Layout.update. Additionally, the Layout would manipulate the LifeCycleHook.component attribute whenever the component instance changed after a render. The former behavior leads to a non-linear code path that's a touch to follow. The latter behavior is the most egregious design issue since there's absolutely no local indication that the component instance can be swapped out (not even a comment).

The new refactor no longer binds component or layout instances to a LifeCycleHook. Instead, the hook simply receives an un-parametrized callback that can be triggered to schedule a render. While some error logs lose clarity (since we can't say what component caused them). This change precludes a need for the layout to ever mutate the hook.

To accommodate this change, the internal representation of the layout's state had to change. Previously, a class-based approach was take, where methods of the state-holding classes were meant to handle all use cases. Now we rely much more heavily on very simple (and mostly static) data structures that have purpose built constructor functions that much more narrowly address each use case.

After these refactors, ComponentTypes no longer needs a unique id attribute. Instead, a unique ID is generated internally which is associated with the LifeCycleState, not component instances since they are inherently transient.

Pull Requests

v0.30.1

:octicon:`milestone` released on 2021-07-13

Removes the usage of the :func:`id` function for generating unique ideas because there were situations where the IDs bound to the lifetime of an object are problematic. Also adds a warning :class:`Deprecation` warning to render functions that include the parameter key. It's been decided that allowing key to be used in this way can lead to confusing bugs.

Pull Requests

v0.30.0

:octicon:`milestone` released on 2021-06-28

With recent changes to the custom component interface, it's now possible to remove all runtime reliance on NPM. Doing so has many virtuous knock-on effects:

  1. Removal of large chunks of code
  2. Greatly simplifies how users dynamically experiment with React component libraries, because their usage no longer requires a build step. Instead they can be loaded in the browser from a CDN that distributes ESM modules.
  3. The built-in client code needs to make fewer assumption about where static resources are located, and as a result, it's also easier to coordinate the server and client code.
  4. Alternate client implementations benefit from this simplicity. Now, it's possible to install @reactpy/client normally and write a loadImportSource() function that looks for route serving the contents of REACTPY_WEB_MODULES_DIR.

This change includes large breaking changes:

  • The CLI is being removed as it won't be needed any longer
  • The reactpy.client is being removed in favor of a stripped down reactpy.web module
  • The REACTPY_CLIENT_BUILD_DIR config option will no longer exist and a new REACTPY_WEB_MODULES_DIR which only contains dynamically linked web modules. While this new directory's location is configurable, it is meant to be transient and should not be re-used across sessions.

The new reactpy.web module takes a simpler approach to constructing import sources and expands upon the logic for resolving imports by allowing exports from URLs to be discovered too. Now, that ReactPy isn't using NPM to dynamically install component libraries reactpy.web instead creates JS modules from template files and links them into REACTPY_WEB_MODULES_DIR. These templates ultimately direct the browser to load the desired library from a CDN.

Pull Requests

v0.29.0

:octicon:`milestone` released on 2021-06-20

Contains breaking changes, the most significant of which are:

  • Moves the runtime client build directory to a "user data" directory rather a directory where ReactPy's code was installed. This has the advantage of not requiring write permissions to rebuild the client if ReactPy was installed globally rather than in a virtual environment.
  • The custom JS component interface has been reworked to expose an API similar to the createElement, render, unmountComponentAtNode functions from React.

Issues Fixed:

Highlighted Commits:

v0.28.0

:octicon:`milestone` released on 2021-06-01

Includes a wide variety of improvements:

  • support currentTime attr of audio/video elements
  • support for the files attribute from the target of input elements
  • model children are passed to the Javascript mount() function
  • began to add tests to client-side javascript
  • add a mountLayoutWithWebSocket function to @reactpy/client

and breaking changes, the most significant of which are:

  • Refactor existing server implementations as functions adhering to a protocol. This greatly simplified much of the code responsible for setting up servers and avoids the use of inheritance.
  • Switch to a monorepo-style structure for Javascript enabling a greater separation of concerns and common workspace scripts in package.json.
  • Use a loadImportSource() function instead of trying to infer the path to dynamic modules which was brittle and inflexible. Allowing the specific client implementation to discover where "import sources" are located means @reactpy/client doesn't need to try and devise a solution that will work for all cases. The fallout from this change is the addition of importSource.sourceType which, for the moment can either be "NAME" or "URL" where the former indicates the client is expected to know where to find a module of that name, and the latter should (usually) be passed on to import()

Issues Fixed:

Highlighted Commits:

v0.27.0

:octicon:`milestone` released on 2021-05-14

Introduces changes to the interface for custom Javascript components. This now allows JS modules to export a mount(element, component, props) function which can be used to bind new elements to the DOM instead of using the application's own React instance and specifying React as a peer dependency. This avoids a wide variety of potential issues with implementing custom components and opens up the possibility for a wider variety of component implementations.

Highlighted Commits:

v0.26.0

:octicon:`milestone` released on 2021-05-07

A collection of minor fixes and changes that, as a whole, add up to something requiring a minor release. The most significant addition is a fix for situations where a Layout can raise an error when a component whose state has been delete is rendered. This occurs when element has been unmounted, but a latent event tells the layout it should be updated. For example, when a user clicks a button rapidly, and the resulting update deletes the original button.

Highlighted Commits:

v0.25.0

:octicon:`milestone` released on 2021-04-30

Completely refactors layout dispatcher by switching from a class-based approach to one that leverages pure functions. While the logic itself isn't any simpler, it was easier to implement, and now hopefully understand, correctly. This conversion was motivated by several bugs that had cropped up related to improper usage of anyio.

Issues Fixed:

Highlighted Commits:

v0.24.0

:octicon:`milestone` released on 2021-04-18

This release contains an update that allows components and elements to have "identity". That is, their state can be preserved across updates. Before this point, only the state for the component at the root of an update was preserved. Now though, the state for any component and element with a key that is unique amongst its siblings, will be preserved so long as this is also true for parent elements/components within the scope of the current update. Thus, only when the key of the element or component changes will its state do the same.

In a future update, the default key for all elements and components will be its index with respect to its siblings in the layout. The :attr:`~reactpy.config.REACTPY_FEATURE_INDEX_AS_DEFAULT_KEY` feature flag has been introduced to allow users to enable this behavior early.

Highlighted Commits:

v0.23.1

:octicon:`milestone` released on 2021-04-02

Highlighted Commits:

v0.23.0

:octicon:`milestone` released on 2021-04-01

Highlighted Commits: