-
-
Notifications
You must be signed in to change notification settings - Fork 144
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
Add testing for 'idiomatic way to pass child component lists into an element's constructor' #78
Comments
Sorry, should have used blame to start, however I've read the issue and the related code, and I still may be confused. The upshot seems to be that for every render, nested components must be reinstantiated. I think I can see why that is as the code stands, but it makes natural patterns produce this panic, which is confusing. The obvious pattern is mentioned in #70 - passing and storing components to be nested. This can be worked around as Dave did by passing a closure that returns new instances of the components, but this doesn't seem ideal. I think we can support at least Components by just calling Rerender if diff --git a/dom.go b/dom.go
index 7ee1c9c..12fa374 100644
--- a/dom.go
+++ b/dom.go
@@ -158,8 +158,8 @@ func (h *HTML) restoreHTML(prev *HTML) {
// TODO better list element reuse
for i, nextChild := range h.children {
- nextChildRender := doRender(nextChild)
if i >= len(prev.children) {
+ nextChildRender := doRender(nextChild)
if doRestore(nil, nextChild, nil, nextChildRender) {
continue
}
@@ -167,6 +167,11 @@ func (h *HTML) restoreHTML(prev *HTML) {
continue
}
prevChild := prev.children[i]
+ if c, isComponent := nextChild.(Component); isComponent && prevChild == nextChild {
+ Rerender(c)
+ continue
+ }
+ nextChildRender := doRender(nextChild)
prevChildRender, ok := prevChild.(*HTML)
if !ok {
prevChildRender = prevChild.(Component).Context().prevRender Not certain on how to handle HTML. Thoughts? |
Removing this panic is NOT a valid thing to do. While you may find a way to make this work technically in the code -- it's not a good thing to be doing in general: a component Render should always propagate downwards into child components, rendering the entire tree of elements from scratch. The motivation for this goes back to the very core of what React & Vecty do: you give us a new render of the DOM, and we handle things behind the scenes. Storing a previous render and returning it subsequently in a secondary render is a lot like manipulating the browser DOM natively -- it's just not a good practice. I understand the desire to use a pattern like that mentioned in #70 (comment) but we'll need to find a way to do it nicely without compromising on the core idea that |
I believe the diff above does what you're describing, but works only for Components, not HTML. It leaves the panic in place. |
Would you be willing to accept a PR for the above patch in the mean time? It solves enough of the issue to work for me (I only need to retain persistent |
Partial fix for hexops#78, only allows re-use of *vecty.Component, not *vecty.HTML
gentle ping @pdf @slimsag @shurcooL I came across this , I'm trying to port material design lite to vecty. I'm still puzzled what does If you don't mind can you enlighten me abit here. Here is my component, it is a tab panel type Panel struct {
vecty.Core
IsActive bool
Name string
ID string
Children vecty.MarkupOrComponentOrHTML
}
func (p *Panel) Render() *vecty.HTML {
c := make(vecty.ClassMap)
c["mdl-tabs__panel "] = true
if p.IsActive {
c["is-active"] = true
}
return elem.Div(
c,
p.Children,
prop.ID(p.ID),
)
} Rerendering this component results into the panic. And I need to rerender this to reflect tab selection, I have tried several setps that seemed to not work. Now I have a feeling I missed something and that my understanding on how vecty work is limited. The Children field is important as user defined content of the tab. Any ideas will be highly appreciated Thanks |
@gernest the PS - MDL is deprecated in favour of material-components-web. |
@pdf thanks. I think I will try to avoid re rendering the component altogether, I will do direct dom manipulation for the same effect.
I heard about that, but I have to start somewhere. If having a full mdl port is possible, then migrating it to |
Partial fix for hexops#78, only allows re-use of *vecty.Component, not *vecty.HTML
Partial fix for hexops#78, only allows re-use of *vecty.Component, not *vecty.HTML
This is most likely fixed, as @pdf said in #124:
I think this is correct, but let's keep this issue around for adding proper testing of this functionality. I also wonder how this will influence or need to be changed based on whatever we do for #115 |
Updated title to reflect what needs to be done here, per my last message. |
Can you tell me why https://github.com/gopherjs/vecty/blob/34ae77073fd923c6ab2f89c234a8ecf76f463cb0/dom.go#L175 exists?
Would it not be safe to just continue here?
The text was updated successfully, but these errors were encountered: