Detect components called as functions (#2461)

* detect components called as functions
* use the existing component name information instead of a thread local
This commit is contained in:
Evan Almloff authored and GitHub committed 2024-06-07 13:55:10 -07:00
1 parent 7efe4d0e49
commit 5024139e01
3 files changed
+38

No files matched your search

+6
View File
@@ -24,6 +24,12 @@ mod scopes;
mod tasks;
mod virtual_dom;
/// Items exported from this module are used in macros and should not be used directly.
#[doc(hidden)]
pub mod internal {
pub use crate::properties::verify_component_called_as_component;
}
pub(crate) mod innerlude {
pub(crate) use crate::any_props::*;
pub use crate::arena::*;
+28
View File
@@ -117,6 +117,34 @@ where
P::builder()
}
/// Make sure that this component is currently running as a component, not a function call
#[doc(hidden)]
#[allow(unused)]
pub fn verify_component_called_as_component<C: ComponentFunction<P, M>, P, M>(component: C) {
#[cfg(debug_assertions)]
{
// We trim WithOwner from the end of the type name for component with a builder that include a special owner which may not match the function name directly
let mut type_name = std::any::type_name::<C>();
if let Some((_, after_colons)) = type_name.rsplit_once("::") {
type_name = after_colons;
}
let component_name = Runtime::with(|rt| {
current_scope_id()
.and_then(|id| rt.get_state(id))
.map(|scope| scope.name)
})
.flatten();
// If we are in a component, and the type name is the same as the active component name, then we can just return
if component_name == Some(type_name) {
return;
}
// Otherwise the component was called like a function, so we should log an error
tracing::error!("It looks like you called the component {type_name} like a function instead of a component. Components should be called with braces like `{type_name} {{ prop: value }}` instead of as a function");
}
}
/// Any component that implements the `ComponentFn` trait can be used as a component.
///
/// This trait is automatically implemented for functions that are in one of the following forms: