reflex
reflex copied to clipboard
on_unmount doesn't work
Describe the bug as you view on rx.cond
Note: is_upload = False (but use ~ on cond)
True: mount -> _upload
False: mount -> rx.fragment
when i upload a file, it trigger on_drop, so is_upload change to True
Now the rx.cond should render the rx.fragment, as my understand this unMount the _upload so it should call his on_unmount calling the rx.redirect to the path.
But, in prod mode this doens't call the on_unmount in _upload
To Reproduce Steps to reproduce the behavior:
class Upload(rx.ComponentState):
_data: bytes | list[bytes]
is_upload: bool = False
async def upload_single(self, upload_files: list[rx.UploadFile]):
if upload_files:
upload_data = await upload_files[0].read()
print(upload_files[0].filename)
self._data = upload_data
self.is_upload = True
async def upload_multiple(self, upload_files: list[rx.UploadFile]):
if upload_files:
upload_data = [await file.read() for file in upload_files]
self._data = upload_data
self.is_upload = True
@classmethod
def get_component(
cls,
id: str,
select_files: Literal["single", "multiple"],
redirect_path: str = "",
) -> rx.Component:
_upload = rx.upload(
rx.vstack(
rx.text("Drag and drop files here or click to select files"),
),
id=id,
on_drop=getattr(cls, f"upload_{select_files}")(
rx.upload_files(upload_id=id)
),
multiple=True if select_files == "multiple" else False,
on_unmount=rx.redirect(redirect_path),
)
new_upload = rx.box(
rx.cond(
~cls.is_upload,
_upload,
rx.fragment(
"Redirecting",
),
)
)
return new_upload
cond calls the redirect on load the page.
class Upload(rx.ComponentState):
_data: bytes | list[bytes]
show_upload: bool = True
async def upload_single(self, upload_files: list[rx.UploadFile]):
if upload_files:
upload_data = await upload_files[0].read()
self._data = upload_data
self.show_upload = False
async def upload_multiple(self, upload_files: list[rx.UploadFile]):
if upload_files:
upload_data = [await file.read() for file in upload_files]
self._data = upload_data
self.show_upload = False
@classmethod
def get_component(
cls,
id: str,
select_files: Literal["single", "multiple"],
redirect_path: str = "",
) -> rx.Component:
_upload = rx.upload(
rx.vstack(
rx.text("Drag and drop files here or click to select files"),
),
id=id,
on_drop=getattr(cls, f"upload_{select_files}")(
rx.upload_files(upload_id=id)
),
multiple=True if select_files == "multiple" else False,
)
new_upload = rx.box(
rx.cond(
cls.show_upload,
_upload,
rx.fragment(
"Redirecting", on_mount=rx.redirect(redirect_path, external=False)
),
)
)
return new_upload
This issue isn't related to reflex but it's how react works. You might want to memoize what uses on_unmount (with @rx.memo). Otherwise react thinks it's still mounted.