hyper-react
hyper-react copied to clipboard
Element is not removed from corresponding buffer when passed as prop unless element is in current buffer
A bug occurred while investigating #122,
class MyComponent
include React::Component
param :tip
def render
div {
params.tip
}
end
end
class TooltipExample
include React::Component
def render
tip = span { "this is a tip" } # <---- key is that the element is generated outside
div(id: "outer") {
MyComponent(tip: tip) # < ---- where its used
}
end
end
will raise
Exception raised while rendering #TooltipExample:0x209c: a component's render method must generate and return exactly 1 element or a string. Instead 2 elements were generated.
The span { "this is a tip" }
is not removed from the correct buffer.
try
params.tip.render
This may fix it..
Yeah, that will fix it, but I think this could be done automatically. Remove it from current @buffer
won't work because span { "this is a tip" }
is in the outer buffer.
it is removed from the outer buffer automatically when it is passed as a param.
We have to do it this way to allow for native components to easily accept Element params.
At least that was my theory :-)
I think my latest attemp show that even manualy “params.tip.render” won't work.
But anyway, I will verify it again and provide a detailed report and continue the discussion on how we can fix this.
Mitch VanDuyn [email protected] 於 2016年12月4日週日 下午9:24 寫道:
it is removed from the outer buffer automatically when it is passed as a param.
We have to do it this way to allow for native components to easily accept Element params.
At least that was my theory :-)
— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/ruby-hyperloop/hyper-react/issues/189#issuecomment-264703779, or mute the thread https://github.com/notifications/unsubscribe-auth/AAzRJVlbRJoWxyu47acSHFspLBFw5-WVks5rEr8HgaJpZM4K806c .
I've verified again, params.tip.render
won't work. But tip = span { "this is a tip" }.delete
will work.
I think the reason is that by wrapping another tag will create a new buffer, thus the automatically removal won't work.
# automatically removal won't work
div(id: "outer") {
MyComponent(tip: tip)
}
# will work
MyComponent(tip: tip)
So I think we might need to keep a reference to the parent buffer, and traversal all the way up to the top buffer to remove the element.
Sure that makes sense, but there is code to automatically remove the element when it's first passed as a parameter. That should be working in this case...
Also sorry, originally I said adding .render would fix it. That's only partially true. .render is needed to render the element, but the bug is that it should already be removed, from the parents buffer
All this applies I guess only to Opal components, which go through rendering context. I think the point of the original issue is we should apply .as_node and .to_n to all elements before shipping them to a native component
Yeah, this one should be considered a separate issue.
OKAY! I got it now (you probably knew this, but I was missing the point...)
In this case we have the element tip
being generated one layer outside where it is used, so yes we will have to search up tree of buffers (which will require a small mod as currently the buffer stack is stored as local vars, but not tough to fix.)
I updated the name of the problem too.