Error on refs on components (#2863)

* error on `ref` with components

r#ref is still allowed, so we reserve the right to reintroduce
the syntax

* fix node_refs example
This commit is contained in:
WorldSEnder 2022-09-13 16:50:33 +02:00 committed by GitHub
parent 5f7dd1d972
commit 8eb9b5a4dc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 19 additions and 17 deletions

View File

@ -8,6 +8,7 @@ pub enum Msg {
pub struct Props {
pub on_hover: Callback<()>,
pub placeholder: AttrValue,
pub input_ref: NodeRef,
}
pub struct InputComponent;
@ -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}

View File

@ -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"
/>

View File

@ -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 })
})

View File

@ -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
|

View File

@ -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};
@ -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");
}
}
#[cfg(target_arch = "wasm32")]