make the root component take no arguments

This commit is contained in:
Evan Almloff committed 2024-01-11 10:48:04 -06:00
1 parent 8fe2515413
commit 404c864246
26 files changed
+46 -47

No files matched your search

@@ -1,6 +1,5 @@
use crate::component_body::ComponentBody; use crate::component_body::ComponentBody;
use quote::ToTokens; use quote::ToTokens;
use syn::{parse_quote, Path};
/// The output produced by a deserializer. /// The output produced by a deserializer.
/// ///
+1 -2
View File
@@ -33,7 +33,7 @@ serde = { version = "1", features = ["derive"], optional = true }
[dev-dependencies] [dev-dependencies]
tokio = { workspace = true, features = ["full"] } tokio = { workspace = true, features = ["full"] }
dioxus = { workspace = true } dioxus = { workspace = true }
dioxus-core = { workspace = true, features = ["internal-testing"] } dioxus-core = { workspace = true }
dioxus-html = { workspace = true, features = ["serialize"] } dioxus-html = { workspace = true, features = ["serialize"] }
pretty_assertions = "1.3.0" pretty_assertions = "1.3.0"
rand = "0.8.5" rand = "0.8.5"
@@ -43,4 +43,3 @@ trybuild = "1.0"
[features] [features]
default = [] default = []
serialize = ["serde"] serialize = ["serde"]
internal-testing = []
+1 -1
View File
@@ -38,7 +38,7 @@ First, start with your app:
use dioxus::prelude::*; use dioxus::prelude::*;
// First, declare a root component // First, declare a root component
fn app(cx: Scope) -> Element { fn app() -> Element {
cx.render(rsx!{ cx.render(rsx!{
div { "hello world" } div { "hello world" }
}) })
+1 -1
View File
@@ -2,7 +2,7 @@ use dioxus::prelude::*;
fn main() {} fn main() {}
fn app(cx: Scope) -> Element { fn app() -> Element {
let count: &RefCell<Vec<Element>> = cx.use_hook(|| RefCell::new(Vec::new())); let count: &RefCell<Vec<Element>> = cx.use_hook(|| RefCell::new(Vec::new()));
render! { render! {
@@ -1,7 +1,7 @@
error[E0521]: borrowed data escapes outside of function error[E0521]: borrowed data escapes outside of function
--> compile_tests/props_safety.rs:8:5 --> compile_tests/props_safety.rs:8:5
| |
5 | fn app(cx: Scope) -> Element { 5 | fn app() -> Element {
| -- | --
| | | |
| `cx` is a reference that is only valid in the function body | `cx` is a reference that is only valid in the function body
@@ -2,7 +2,7 @@ use dioxus::prelude::*;
fn main() {} fn main() {}
fn app(cx: Scope) -> Element { fn app() -> Element {
let count = vec![1, 2, 3]; let count = vec![1, 2, 3];
render! { render! {
+1 -1
View File
@@ -62,7 +62,7 @@ impl<const A: bool> FragmentBuilder<A> {
/// ## Example /// ## Example
/// ///
/// ```rust, ignore /// ```rust, ignore
/// fn App(cx: Scope) -> Element { /// fn App() -> Element {
/// cx.render(rsx!{ /// cx.render(rsx!{
/// CustomCard { /// CustomCard {
/// h1 {} /// h1 {}
+1 -1
View File
@@ -115,7 +115,7 @@ impl Runtime {
/// let virtual_dom = VirtualDom::new(app); /// let virtual_dom = VirtualDom::new(app);
/// } /// }
/// ///
/// fn app(cx: Scope) -> Element { /// fn app() -> Element {
/// render!{ Component { runtime: Runtime::current().unwrap() } } /// render!{ Component { runtime: Runtime::current().unwrap() } }
/// } /// }
/// ///
+4 -7
View File
@@ -88,7 +88,7 @@ use std::{any::Any, cell::Cell, collections::BTreeSet, future::Future, rc::Rc};
/// ///
/// ```rust /// ```rust
/// # use dioxus::prelude::*; /// # use dioxus::prelude::*;
/// # fn App(cx: Scope) -> Element { cx.render(rsx! { div {} }) } /// # fn App() -> Element { cx.render(rsx! { div {} }) }
/// ///
/// let mut vdom = VirtualDom::new(App); /// let mut vdom = VirtualDom::new(App);
/// let edits = vdom.rebuild(); /// let edits = vdom.rebuild();
@@ -127,7 +127,7 @@ use std::{any::Any, cell::Cell, collections::BTreeSet, future::Future, rc::Rc};
/// Putting everything together, you can build an event loop around Dioxus by using the methods outlined above. /// Putting everything together, you can build an event loop around Dioxus by using the methods outlined above.
/// ```rust, ignore /// ```rust, ignore
/// #[component] /// #[component]
/// fn App(cx: Scope) -> Element { /// fn App() -> Element {
/// cx.render(rsx! { /// cx.render(rsx! {
/// div { "Hello World" } /// div { "Hello World" }
/// }) /// })
@@ -226,8 +226,8 @@ impl VirtualDom {
/// ``` /// ```
/// ///
/// Note: the VirtualDom is not progressed, you must either "run_with_deadline" or use "rebuild" to progress it. /// Note: the VirtualDom is not progressed, you must either "run_with_deadline" or use "rebuild" to progress it.
pub fn new(app: fn(()) -> Element) -> Self { pub fn new(app: fn() -> Element) -> Self {
Self::new_with_props(app, ()) Self::new_with_props(|app| app(), app)
} }
/// Create a new VirtualDom with the given properties for the root component. /// Create a new VirtualDom with the given properties for the root component.
@@ -563,7 +563,6 @@ impl VirtualDom {
to.append_children(ElementId(0), m); to.append_children(ElementId(0), m);
} }
#[cfg(features = "internal-testing")]
/// [`VirtualDom::rebuild`] to a vector of mutations for testing purposes /// [`VirtualDom::rebuild`] to a vector of mutations for testing purposes
pub fn rebuild_to_vec(&mut self) -> MutationsVec { pub fn rebuild_to_vec(&mut self) -> MutationsVec {
let mut mutations = MutationsVec::default(); let mut mutations = MutationsVec::default();
@@ -590,7 +589,6 @@ impl VirtualDom {
} }
} }
#[cfg(features = "internal-testing")]
/// [`Self::render_immediate`] to a vector of mutations for testing purposes /// [`Self::render_immediate`] to a vector of mutations for testing purposes
pub fn render_immediate_to_vec(&mut self) -> MutationsVec { pub fn render_immediate_to_vec(&mut self) -> MutationsVec {
let mut mutations = MutationsVec::default(); let mut mutations = MutationsVec::default();
@@ -662,7 +660,6 @@ impl VirtualDom {
} }
} }
#[cfg(features = "internal-testing")]
/// [`Self::render_with_deadline`] to a vector of mutations for testing purposes /// [`Self::render_with_deadline`] to a vector of mutations for testing purposes
pub async fn render_with_deadline_to_vec( pub async fn render_with_deadline_to_vec(
&mut self, &mut self,
+1 -1
View File
@@ -2,7 +2,7 @@
use dioxus::prelude::*; use dioxus::prelude::*;
fn app(cx: Scope) -> Element { fn app() -> Element {
let raw = match generation() % 2 { let raw = match generation() % 2 {
0 => "123.123", 0 => "123.123",
1 => "123.123.123", 1 => "123.123.123",
+1 -1
View File
@@ -3,7 +3,7 @@ use dioxus::prelude::*;
#[test] #[test]
fn state_shares() { fn state_shares() {
fn app(cx: Scope) -> Element { fn app() -> Element {
cx.provide_context(generation() as i32); cx.provide_context(generation() as i32);
render!(child_1 {}) render!(child_1 {})
+3 -3
View File
@@ -6,7 +6,7 @@ use dioxus_core::ElementId;
#[test] #[test]
fn empty_fragment_creates_nothing() { fn empty_fragment_creates_nothing() {
fn app(cx: Scope) -> Element { fn app() -> Element {
render!(()) render!(())
} }
@@ -66,7 +66,7 @@ fn fragments_nested() {
#[test] #[test]
fn fragments_across_components() { fn fragments_across_components() {
fn app(cx: Scope) -> Element { fn app() -> Element {
render! { render! {
demo_child {} demo_child {}
demo_child {} demo_child {}
@@ -88,7 +88,7 @@ fn fragments_across_components() {
#[test] #[test]
fn list_fragments() { fn list_fragments() {
fn app(cx: Scope) -> Element { fn app() -> Element {
render!( render!(
h1 { "hello" } h1 { "hello" }
(0..6).map(|f| render!( span { "{f}" })) (0..6).map(|f| render!( span { "{f}" }))
+1 -1
View File
@@ -8,7 +8,7 @@ use dioxus_core::ElementId;
// In Dioxus, we memoize the render! body and simplify it down to a few template loads // In Dioxus, we memoize the render! body and simplify it down to a few template loads
// //
// Also note that the IDs increase linearly. This lets us drive a vec on the renderer for O(1) re-indexing // Also note that the IDs increase linearly. This lets us drive a vec on the renderer for O(1) re-indexing
fn app(cx: Scope) -> Element { fn app() -> Element {
render! { render! {
div { div {
(0..3).map(|i| render! { (0..3).map(|i| render! {
+3 -3
View File
@@ -6,7 +6,7 @@ use dioxus_core::ElementId;
#[test] #[test]
fn nested_passthru_creates() { fn nested_passthru_creates() {
#[component] #[component]
fn App(cx: Scope) -> Element { fn App() -> Element {
render! { render! {
PassThru { PassThru {
PassThru { PassThru {
@@ -39,7 +39,7 @@ fn nested_passthru_creates() {
#[test] #[test]
fn nested_passthru_creates_add() { fn nested_passthru_creates_add() {
#[component] #[component]
fn App(cx: Scope) -> Element { fn App() -> Element {
render! { render! {
ChildComp { ChildComp {
"1" "1"
@@ -81,7 +81,7 @@ fn nested_passthru_creates_add() {
#[test] #[test]
fn dynamic_node_as_root() { fn dynamic_node_as_root() {
#[component] #[component]
fn App(cx: Scope) -> Element { fn App() -> Element {
let a = 123; let a = 123;
let b = 456; let b = 456;
render! { "{a}", "{b}" } render! { "{a}", "{b}" }
+1 -1
View File
@@ -7,7 +7,7 @@ use dioxus::prelude::*;
/// different pointers /// different pointers
#[test] #[test]
fn component_swap() { fn component_swap() {
fn app(cx: Scope) -> Element { fn app() -> Element {
let render_phase = cx.use_hook(|| 0); let render_phase = cx.use_hook(|| 0);
*render_phase += 1; *render_phase += 1;
+2 -2
View File
@@ -4,7 +4,7 @@ use dioxus_core::ElementId;
#[test] #[test]
fn text_diff() { fn text_diff() {
fn app(cx: Scope) -> Element { fn app() -> Element {
let gen = generation(); let gen = generation();
render!( h1 { "hello {gen}" } ) render!( h1 { "hello {gen}" } )
} }
@@ -33,7 +33,7 @@ fn text_diff() {
#[test] #[test]
fn element_swap() { fn element_swap() {
fn app(cx: Scope) -> Element { fn app() -> Element {
let gen = generation(); let gen = generation();
match gen % 2 { match gen % 2 {
+1 -1
View File
@@ -8,7 +8,7 @@ fn catches_panic() {
_ = dom.rebuild_to_vec(&mut dioxus_core::NoOpMutations); _ = dom.rebuild_to_vec(&mut dioxus_core::NoOpMutations);
} }
fn app(cx: Scope) -> Element { fn app() -> Element {
render! { render! {
div { div {
h1 { "Title" } h1 { "Title" }
+1 -1
View File
@@ -51,7 +51,7 @@ fn events_propagate() {
assert_eq!(*CLICKS.lock().unwrap(), 3); assert_eq!(*CLICKS.lock().unwrap(), 3);
} }
fn app(cx: Scope) -> Element { fn app() -> Element {
render! { render! {
div { onclick: move |_| { div { onclick: move |_| {
println!("top clicked"); println!("top clicked");
+2 -2
View File
@@ -41,7 +41,7 @@ fn manual_diffing() {
#[test] #[test]
fn events_generate() { fn events_generate() {
set_event_converter(Box::new(SerializedHtmlEventConverter)); set_event_converter(Box::new(SerializedHtmlEventConverter));
fn app(cx: Scope) -> Element { fn app() -> Element {
let count = cx.use_hook(|| 0); let count = cx.use_hook(|| 0);
match *count { match *count {
@@ -79,7 +79,7 @@ fn events_generate() {
// #[test] // #[test]
// fn components_generate() { // fn components_generate() {
// fn app(cx: Scope) -> Element { // fn app() -> Element {
// let render_phase = cx.use_hook(|| 0); // let render_phase = cx.use_hook(|| 0);
// *render_phase += 1; // *render_phase += 1;
+1 -1
View File
@@ -24,7 +24,7 @@ fn miri_rollover() {
} }
#[component] #[component]
fn App(cx: Scope) -> Element { fn App() -> Element {
let mut idx = use_state(cx, || 0); let mut idx = use_state(cx, || 0);
let onhover = |_| println!("go!"); let onhover = |_| println!("go!");
+5 -5
View File
@@ -3,7 +3,7 @@ use dioxus::prelude::*;
#[test] #[test]
fn app_drops() { fn app_drops() {
#[component] #[component]
fn App(cx: Scope) -> Element { fn App() -> Element {
render! { div {} } render! { div {} }
} }
@@ -17,7 +17,7 @@ fn app_drops() {
#[test] #[test]
fn hooks_drop() { fn hooks_drop() {
#[component] #[component]
fn App(cx: Scope) -> Element { fn App() -> Element {
cx.use_hook(|| String::from("asd")); cx.use_hook(|| String::from("asd"));
cx.use_hook(|| String::from("asd")); cx.use_hook(|| String::from("asd"));
cx.use_hook(|| String::from("asd")); cx.use_hook(|| String::from("asd"));
@@ -36,7 +36,7 @@ fn hooks_drop() {
#[test] #[test]
fn contexts_drop() { fn contexts_drop() {
#[component] #[component]
fn App(cx: Scope) -> Element { fn App() -> Element {
cx.provide_context(String::from("asd")); cx.provide_context(String::from("asd"));
render! { render! {
@@ -61,7 +61,7 @@ fn contexts_drop() {
#[test] #[test]
fn tasks_drop() { fn tasks_drop() {
#[component] #[component]
fn App(cx: Scope) -> Element { fn App() -> Element {
cx.spawn(async { cx.spawn(async {
// tokio::time::sleep(std::time::Duration::from_millis(100000)).await; // tokio::time::sleep(std::time::Duration::from_millis(100000)).await;
}); });
@@ -93,7 +93,7 @@ fn root_props_drop() {
#[test] #[test]
fn diffing_drops_old() { fn diffing_drops_old() {
#[component] #[component]
fn App(cx: Scope) -> Element { fn App() -> Element {
render! { render! {
div { div {
match generation() % 2 { match generation() % 2 {
+3 -3
View File
@@ -9,7 +9,7 @@ use dioxus::prelude::*;
/// When miri runs, it'll let us know if we leaked or aliased. /// When miri runs, it'll let us know if we leaked or aliased.
#[test] #[test]
fn test_memory_leak() { fn test_memory_leak() {
fn app(cx: Scope) -> Element { fn app() -> Element {
let val = generation(); let val = generation();
cx.spawn(async {}); cx.spawn(async {});
@@ -69,7 +69,7 @@ fn test_memory_leak() {
#[test] #[test]
fn memo_works_properly() { fn memo_works_properly() {
fn app(cx: Scope) -> Element { fn app() -> Element {
let val = generation(); let val = generation();
if val == 2 || val == 4 { if val == 2 || val == 4 {
@@ -142,7 +142,7 @@ fn supports_async() {
use std::time::Duration; use std::time::Duration;
use tokio::time::sleep; use tokio::time::sleep;
fn app(cx: Scope) -> Element { fn app() -> Element {
let colors = use_state(cx, || vec!["green", "blue", "red"]); let colors = use_state(cx, || vec!["green", "blue", "red"]);
let padding = use_state(cx, || 10); let padding = use_state(cx, || 10);
+1 -1
View File
@@ -19,7 +19,7 @@ fn it_works() {
}); });
} }
fn app(cx: Scope) -> Element { fn app() -> Element {
render!( render!(
div { div {
"Waiting for... " "Waiting for... "
+1 -1
View File
@@ -8,7 +8,7 @@ async fn it_works() {
static POLL_COUNT: AtomicUsize = AtomicUsize::new(0); static POLL_COUNT: AtomicUsize = AtomicUsize::new(0);
fn app(cx: Scope) -> Element { fn app() -> Element {
cx.use_hook(|| { cx.use_hook(|| {
cx.spawn(async { cx.spawn(async {
for x in 0..10 { for x in 0..10 {
+2 -2
View File
@@ -76,8 +76,8 @@ use wry::{application::window::WindowId, webview::WebContext};
/// }) /// })
/// } /// }
/// ``` /// ```
pub fn launch(root: Component) { pub fn launch(root: fn() -> Element) {
launch_with_props(root, (), Config::default()) launch_with_props(|root| root(), root, Config::default())
} }
/// Launch the WebView and run the event loop, with configuration. /// Launch the WebView and run the event loop, with configuration.
+6 -2
View File
@@ -105,8 +105,12 @@ mod rehydrate;
/// render!(div {"hello world"}) /// render!(div {"hello world"})
/// } /// }
/// ``` /// ```
pub fn launch(root_component: fn(()) -> Element) { pub fn launch(root_component: fn() -> Element) {
launch_with_props(root_component, (), Config::default()); launch_with_props(
|root_component| root_component(),
root_component,
Config::default(),
);
} }
/// Launch your app and run the event loop, with configuration. /// Launch your app and run the event loop, with configuration.