Skip to content
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

Error on refs on components #2863

Merged
merged 3 commits into from
Sep 13, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 2 additions & 0 deletions examples/node_refs/src/input.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ pub enum Msg {
pub struct Props {
pub on_hover: Callback<()>,
pub placeholder: AttrValue,
pub input_ref: NodeRef,
}

pub struct InputComponent;
Expand All @@ -33,6 +34,7 @@ impl Component for InputComponent {
let placeholder = ctx.props().placeholder.clone();
html! {
<input
ref={&ctx.props().input_ref}
type="text"
class="input-component"
placeholder={placeholder}
Expand Down
2 changes: 1 addition & 1 deletion examples/node_refs/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ impl Component for App {
<div class="input-container">
<label>{ "Password" }</label>
<InputComponent
ref={&self.refs[1]}
input_ref={&self.refs[1]}
on_hover={ctx.link().callback(|_| Msg::HoverIndex(1))}
placeholder="password"
/>
Expand Down
10 changes: 9 additions & 1 deletion packages/yew-macro/src/html_tree/html_component.rs
Original file line number Diff line number Diff line change
Expand Up @@ -257,7 +257,15 @@ impl Parse for HtmlComponentOpen {
fn parse(input: ParseStream) -> syn::Result<Self> {
TagTokens::parse_start_content(input, |input, tag| {
let ty = input.parse()?;
let props = input.parse()?;
let props: ComponentProps = input.parse()?;

if let Some(ref node_ref) = props.special().node_ref {
return Err(syn::Error::new_spanned(
&node_ref.label,
"cannot use `ref` with components. If you want to specify a property, use \
`r#ref` here instead.",
));
}

Ok(Self { tag, ty, props })
})
Expand Down
6 changes: 6 additions & 0 deletions packages/yew-macro/tests/html_macro/component-fail.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -285,6 +285,12 @@ error: `int` can only be specified once but is given here again
90 | html! { <Child int=1 int=2 int=3 /> };
| ^^^

error: cannot use `ref` with components. If you want to specify a property, use `r#ref` here instead.
--> tests/html_macro/component-fail.rs:94:26
|
94 | html! { <Child int=1 ref={()} /> };
| ^^^

error: `ref` can only be specified once
--> tests/html_macro/component-fail.rs:95:35
|
Expand Down
16 changes: 1 addition & 15 deletions packages/yew/src/dom_bundle/bcomp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,7 @@ mod tests {
use web_sys::Element;

use super::*;
use crate::dom_bundle::{Reconcilable, ReconcileTarget};
use crate::dom_bundle::Reconcilable;
use crate::virtual_dom::{Key, VChild, VNode};
use crate::{html, scheduler, Children, Component, Context, Html, NodeRef, Properties};

Expand Down Expand Up @@ -393,20 +393,6 @@ mod tests {
};
assert_eq!(get_html(for_method, &root, &scope, &parent), expected_html);
}

#[test]
fn component_node_ref_stays_none() {
let (root, scope, parent) = setup_parent();

let node_ref = NodeRef::default();
let elem = html! { <Comp ref={node_ref.clone()}></Comp> };
let (_, elem) = elem.attach(&root, &scope, &parent, NodeRef::default());
scheduler::start_now();
assert!(node_ref.get().is_none(), "components don't have node refs");
elem.detach(&root, &parent, false);
scheduler::start_now();
assert!(node_ref.get().is_none(), "components don't have node refs");
}
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Test removed because this is now a compile error, see component-fail.stderr above.

}

#[cfg(target_arch = "wasm32")]
Expand Down