Skip to content

Nested context does not update value if outer context should not render #846

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
Archmonger opened this issue Dec 1, 2022 · 13 comments · Fixed by #870
Closed

Nested context does not update value if outer context should not render #846

Archmonger opened this issue Dec 1, 2022 · 13 comments · Fixed by #870
Labels
priority-1-high Should be resolved ASAP.
Milestone

Comments

@Archmonger
Copy link
Contributor

Current Situation

ReactJS appears to support nested context.

However, in IDOM situations like the following simply don't render...

    return ModalStateContext(
        HomepageStateContext(
            navbar(),
            modal(),
            sidebar(),
            viewport_loading_animation(),
            viewport(),
            backdrop(),
            value=home_state,
        ),
        value=modal_state,
    )

Proposed Actions

Modify the ContextProvider to support nested contexts.

@Archmonger Archmonger added priority-2-moderate Should be resolved on a reasonable timeline. type-revision About a change in functionality or behavior labels Dec 1, 2022
@Archmonger Archmonger added this to the 1.0 milestone Dec 1, 2022
@rmorshea
Copy link
Collaborator

rmorshea commented Dec 1, 2022

I'm unable to reproduce - this test passes. Can you provide sample code I can use to test this?

@rmorshea rmorshea added type: bug and removed type-revision About a change in functionality or behavior labels Dec 1, 2022
@Archmonger
Copy link
Contributor Author

Archmonger commented Dec 2, 2022

EDIT: Wrong issue. This comment can be ignored.

I can attempt to generate an example tomorrow.

I think it's about nested contexts on conditionally rendered components. When the conditionally rendered component is gone, seems to break use_context.

@rmorshea
Copy link
Collaborator

rmorshea commented Dec 2, 2022

My suspicion here is that this logic is wrong. After reading a bit, context providers don't actually stop descendants that do not use_context from rendering. That is, should_render ought to always return True. Given that, this ability to skip a render seems like a remnant of React's class-based components I might actually remove this method entirely.

@rmorshea
Copy link
Collaborator

rmorshea commented Dec 2, 2022

This fact, that presently in IDOM the descendants of a context (except those that use_context) skip a render if the context's value did not change, may be what you're observing.

@Archmonger
Copy link
Contributor Author

Archmonger commented Dec 2, 2022

We might want to develop memo components before removing the should_render value.

Also it's worth double checking that the one commenter on stackoverflow is telling the truth.

@rmorshea
Copy link
Collaborator

rmorshea commented Dec 3, 2022

In ReactJS, useMemo was intended to be a replacement for shouldComponentUpdate (the analog to should_render).

@Archmonger Archmonger linked a pull request Dec 4, 2022 that will close this issue
3 tasks
@Archmonger
Copy link
Contributor Author

Archmonger commented Dec 4, 2022

I think the issue I'm seeing might be set_state getting mangled if it's a dataclass(frozen=True) attribute within a nested context...

Still trying to dig a bit deeper and confirm this.

The issues seem fairly random though, sometimes calling set_state in this situation causes assert parent is not None, "detached model state" to occur, and other times simply nothing occurs.

@Archmonger
Copy link
Contributor Author

Archmonger commented Dec 30, 2022

I've committed an example of problematic nested contexts.

It seems like calling set_state (that is contained within an object in a sub-context) will not send an event onto the layout render queue.

Issue can be detected by creating several app store subcategories, and then clicking through them. Also, if you click on the "details" button on any card (triggers a re-render of the page), then all children within my sub-context go poof.

This issue can be replicated by pulling down Archmonger/Conreq@f21ea6e

@Archmonger Archmonger added priority-1-high Should be resolved ASAP. and removed priority-2-moderate Should be resolved on a reasonable timeline. labels Dec 31, 2022
@Archmonger Archmonger changed the title Supported nested contexts Nested contexts containing set_state are broken Dec 31, 2022
@Archmonger
Copy link
Contributor Author

Maybe there's an additional layer to consider with conditionally rendered components. I wasn't able to reproduce using this example

from typing import Callable
from idom import component, hooks, html, run
from dataclasses import dataclass
from flask import Flask

@dataclass
class State:
    value: int = 0
    set_value: Callable = lambda x: None


@dataclass
class RootState:
    doesnt_matter: int = 0


RootContext = hooks.create_context(RootState())
SubContext = hooks.create_context(State())


@component
def root():
    return RootContext(child(), value=RootState(123))


@component
def child():
    state, set_state = hooks.use_state(State(value=456))
    state.set_value = set_state

    print("`state.value` value should start as 456 change to 666 when clicked: ", state)

    return SubContext(
        str(state),
        html.button(
            {"onClick": lambda x: set_state(State(value=666))},
            "Click Me",
        ),
        value=state,
    )


run(root)

@rmorshea
Copy link
Collaborator

rmorshea commented Jan 7, 2023

I think we can remove the should_render method entirely. It seems like a vestige from old class-based components.

@rmorshea rmorshea mentioned this issue Jan 7, 2023
3 tasks
@rmorshea rmorshea changed the title Nested contexts containing set_state are broken Nested context does no update value if outer context should not render Jan 8, 2023
@Archmonger Archmonger changed the title Nested context does no update value if outer context should not render Nested context does not update value if outer context should not render Jan 21, 2023
@Archmonger
Copy link
Contributor Author

There is somehow still some lingering issues with this fix.

Do you have time this weekend for me to demo?

@rmorshea
Copy link
Collaborator

Sure. Sat or mid-day Sun work

@Archmonger
Copy link
Contributor Author

Spoke too soon. It was an issue on my end.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
priority-1-high Should be resolved ASAP.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants