pub trait EventsExtension: AttributeBuilderTarget + Sized {
Show 93 methods
// Provided methods
fn onanimationstart<__Marker>(
self,
event_handler: impl EventHandlerValue<AnimationData, __Marker>,
) -> <Self as AttributeBuilderTarget>::Output { ... }
fn onanimationend<__Marker>(
self,
event_handler: impl EventHandlerValue<AnimationData, __Marker>,
) -> <Self as AttributeBuilderTarget>::Output { ... }
fn onanimationiteration<__Marker>(
self,
event_handler: impl EventHandlerValue<AnimationData, __Marker>,
) -> <Self as AttributeBuilderTarget>::Output { ... }
fn onbeforeinput<__Marker>(
self,
event_handler: impl EventHandlerValue<BeforeInputData, __Marker>,
) -> <Self as AttributeBuilderTarget>::Output { ... }
fn oncancel<__Marker>(
self,
event_handler: impl EventHandlerValue<CancelData, __Marker>,
) -> <Self as AttributeBuilderTarget>::Output { ... }
fn oncopy<__Marker>(
self,
event_handler: impl EventHandlerValue<ClipboardData, __Marker>,
) -> <Self as AttributeBuilderTarget>::Output { ... }
fn oncut<__Marker>(
self,
event_handler: impl EventHandlerValue<ClipboardData, __Marker>,
) -> <Self as AttributeBuilderTarget>::Output { ... }
fn onpaste<__Marker>(
self,
event_handler: impl EventHandlerValue<ClipboardData, __Marker>,
) -> <Self as AttributeBuilderTarget>::Output { ... }
fn oncompositionstart<__Marker>(
self,
event_handler: impl EventHandlerValue<CompositionData, __Marker>,
) -> <Self as AttributeBuilderTarget>::Output { ... }
fn oncompositionend<__Marker>(
self,
event_handler: impl EventHandlerValue<CompositionData, __Marker>,
) -> <Self as AttributeBuilderTarget>::Output { ... }
fn oncompositionupdate<__Marker>(
self,
event_handler: impl EventHandlerValue<CompositionData, __Marker>,
) -> <Self as AttributeBuilderTarget>::Output { ... }
fn ondrag<__Marker>(
self,
event_handler: impl EventHandlerValue<DragData, __Marker>,
) -> <Self as AttributeBuilderTarget>::Output { ... }
fn ondragend<__Marker>(
self,
event_handler: impl EventHandlerValue<DragData, __Marker>,
) -> <Self as AttributeBuilderTarget>::Output { ... }
fn ondragenter<__Marker>(
self,
event_handler: impl EventHandlerValue<DragData, __Marker>,
) -> <Self as AttributeBuilderTarget>::Output { ... }
fn ondragexit<__Marker>(
self,
event_handler: impl EventHandlerValue<DragData, __Marker>,
) -> <Self as AttributeBuilderTarget>::Output { ... }
fn ondragleave<__Marker>(
self,
event_handler: impl EventHandlerValue<DragData, __Marker>,
) -> <Self as AttributeBuilderTarget>::Output { ... }
fn ondragover<__Marker>(
self,
event_handler: impl EventHandlerValue<DragData, __Marker>,
) -> <Self as AttributeBuilderTarget>::Output { ... }
fn ondragstart<__Marker>(
self,
event_handler: impl EventHandlerValue<DragData, __Marker>,
) -> <Self as AttributeBuilderTarget>::Output { ... }
fn ondrop<__Marker>(
self,
event_handler: impl EventHandlerValue<DragData, __Marker>,
) -> <Self as AttributeBuilderTarget>::Output { ... }
fn onfocus<__Marker>(
self,
event_handler: impl EventHandlerValue<FocusData, __Marker>,
) -> <Self as AttributeBuilderTarget>::Output { ... }
fn onfocusout<__Marker>(
self,
event_handler: impl EventHandlerValue<FocusData, __Marker>,
) -> <Self as AttributeBuilderTarget>::Output { ... }
fn onfocusin<__Marker>(
self,
event_handler: impl EventHandlerValue<FocusData, __Marker>,
) -> <Self as AttributeBuilderTarget>::Output { ... }
fn onblur<__Marker>(
self,
event_handler: impl EventHandlerValue<FocusData, __Marker>,
) -> <Self as AttributeBuilderTarget>::Output { ... }
fn onchange<__Marker>(
self,
event_handler: impl EventHandlerValue<FormData, __Marker>,
) -> <Self as AttributeBuilderTarget>::Output { ... }
fn oninput<__Marker>(
self,
event_handler: impl EventHandlerValue<FormData, __Marker>,
) -> <Self as AttributeBuilderTarget>::Output { ... }
fn oninvalid<__Marker>(
self,
event_handler: impl EventHandlerValue<FormData, __Marker>,
) -> <Self as AttributeBuilderTarget>::Output { ... }
fn onreset<__Marker>(
self,
event_handler: impl EventHandlerValue<FormData, __Marker>,
) -> <Self as AttributeBuilderTarget>::Output { ... }
fn onsubmit<__Marker>(
self,
event_handler: impl EventHandlerValue<FormData, __Marker>,
) -> <Self as AttributeBuilderTarget>::Output { ... }
fn onerror<__Marker>(
self,
event_handler: impl EventHandlerValue<ImageData, __Marker>,
) -> <Self as AttributeBuilderTarget>::Output { ... }
fn onload<__Marker>(
self,
event_handler: impl EventHandlerValue<ImageData, __Marker>,
) -> <Self as AttributeBuilderTarget>::Output { ... }
fn onkeydown<__Marker>(
self,
event_handler: impl EventHandlerValue<KeyboardData, __Marker>,
) -> <Self as AttributeBuilderTarget>::Output { ... }
fn onkeypress<__Marker>(
self,
event_handler: impl EventHandlerValue<KeyboardData, __Marker>,
) -> <Self as AttributeBuilderTarget>::Output { ... }
fn onkeyup<__Marker>(
self,
event_handler: impl EventHandlerValue<KeyboardData, __Marker>,
) -> <Self as AttributeBuilderTarget>::Output { ... }
fn onabort<__Marker>(
self,
event_handler: impl EventHandlerValue<MediaData, __Marker>,
) -> <Self as AttributeBuilderTarget>::Output { ... }
fn oncanplay<__Marker>(
self,
event_handler: impl EventHandlerValue<MediaData, __Marker>,
) -> <Self as AttributeBuilderTarget>::Output { ... }
fn oncanplaythrough<__Marker>(
self,
event_handler: impl EventHandlerValue<MediaData, __Marker>,
) -> <Self as AttributeBuilderTarget>::Output { ... }
fn ondurationchange<__Marker>(
self,
event_handler: impl EventHandlerValue<MediaData, __Marker>,
) -> <Self as AttributeBuilderTarget>::Output { ... }
fn onemptied<__Marker>(
self,
event_handler: impl EventHandlerValue<MediaData, __Marker>,
) -> <Self as AttributeBuilderTarget>::Output { ... }
fn onencrypted<__Marker>(
self,
event_handler: impl EventHandlerValue<MediaData, __Marker>,
) -> <Self as AttributeBuilderTarget>::Output { ... }
fn onended<__Marker>(
self,
event_handler: impl EventHandlerValue<MediaData, __Marker>,
) -> <Self as AttributeBuilderTarget>::Output { ... }
fn onloadeddata<__Marker>(
self,
event_handler: impl EventHandlerValue<MediaData, __Marker>,
) -> <Self as AttributeBuilderTarget>::Output { ... }
fn onloadedmetadata<__Marker>(
self,
event_handler: impl EventHandlerValue<MediaData, __Marker>,
) -> <Self as AttributeBuilderTarget>::Output { ... }
fn onloadstart<__Marker>(
self,
event_handler: impl EventHandlerValue<MediaData, __Marker>,
) -> <Self as AttributeBuilderTarget>::Output { ... }
fn onpause<__Marker>(
self,
event_handler: impl EventHandlerValue<MediaData, __Marker>,
) -> <Self as AttributeBuilderTarget>::Output { ... }
fn onplay<__Marker>(
self,
event_handler: impl EventHandlerValue<MediaData, __Marker>,
) -> <Self as AttributeBuilderTarget>::Output { ... }
fn onplaying<__Marker>(
self,
event_handler: impl EventHandlerValue<MediaData, __Marker>,
) -> <Self as AttributeBuilderTarget>::Output { ... }
fn onprogress<__Marker>(
self,
event_handler: impl EventHandlerValue<MediaData, __Marker>,
) -> <Self as AttributeBuilderTarget>::Output { ... }
fn onratechange<__Marker>(
self,
event_handler: impl EventHandlerValue<MediaData, __Marker>,
) -> <Self as AttributeBuilderTarget>::Output { ... }
fn onseeked<__Marker>(
self,
event_handler: impl EventHandlerValue<MediaData, __Marker>,
) -> <Self as AttributeBuilderTarget>::Output { ... }
fn onseeking<__Marker>(
self,
event_handler: impl EventHandlerValue<MediaData, __Marker>,
) -> <Self as AttributeBuilderTarget>::Output { ... }
fn onstalled<__Marker>(
self,
event_handler: impl EventHandlerValue<MediaData, __Marker>,
) -> <Self as AttributeBuilderTarget>::Output { ... }
fn onsuspend<__Marker>(
self,
event_handler: impl EventHandlerValue<MediaData, __Marker>,
) -> <Self as AttributeBuilderTarget>::Output { ... }
fn ontimeupdate<__Marker>(
self,
event_handler: impl EventHandlerValue<MediaData, __Marker>,
) -> <Self as AttributeBuilderTarget>::Output { ... }
fn onvolumechange<__Marker>(
self,
event_handler: impl EventHandlerValue<MediaData, __Marker>,
) -> <Self as AttributeBuilderTarget>::Output { ... }
fn onwaiting<__Marker>(
self,
event_handler: impl EventHandlerValue<MediaData, __Marker>,
) -> <Self as AttributeBuilderTarget>::Output { ... }
fn onmounted<__Marker>(
self,
event_handler: impl EventHandlerValue<MountedData, __Marker>,
) -> <Self as AttributeBuilderTarget>::Output { ... }
fn onclick<__Marker>(
self,
event_handler: impl EventHandlerValue<MouseData, __Marker>,
) -> <Self as AttributeBuilderTarget>::Output { ... }
fn oncontextmenu<__Marker>(
self,
event_handler: impl EventHandlerValue<MouseData, __Marker>,
) -> <Self as AttributeBuilderTarget>::Output { ... }
fn ondblclick<__Marker>(
self,
event_handler: impl EventHandlerValue<MouseData, __Marker>,
) -> <Self as AttributeBuilderTarget>::Output { ... }
fn ondoubleclick<__Marker>(
self,
event_handler: impl EventHandlerValue<MouseData, __Marker>,
) -> <Self as AttributeBuilderTarget>::Output { ... }
fn onmousedown<__Marker>(
self,
event_handler: impl EventHandlerValue<MouseData, __Marker>,
) -> <Self as AttributeBuilderTarget>::Output { ... }
fn onmouseenter<__Marker>(
self,
event_handler: impl EventHandlerValue<MouseData, __Marker>,
) -> <Self as AttributeBuilderTarget>::Output { ... }
fn onmouseleave<__Marker>(
self,
event_handler: impl EventHandlerValue<MouseData, __Marker>,
) -> <Self as AttributeBuilderTarget>::Output { ... }
fn onmousemove<__Marker>(
self,
event_handler: impl EventHandlerValue<MouseData, __Marker>,
) -> <Self as AttributeBuilderTarget>::Output { ... }
fn onmouseout<__Marker>(
self,
event_handler: impl EventHandlerValue<MouseData, __Marker>,
) -> <Self as AttributeBuilderTarget>::Output { ... }
fn onmouseover<__Marker>(
self,
event_handler: impl EventHandlerValue<MouseData, __Marker>,
) -> <Self as AttributeBuilderTarget>::Output { ... }
fn onmouseup<__Marker>(
self,
event_handler: impl EventHandlerValue<MouseData, __Marker>,
) -> <Self as AttributeBuilderTarget>::Output { ... }
fn onpointerdown<__Marker>(
self,
event_handler: impl EventHandlerValue<PointerData, __Marker>,
) -> <Self as AttributeBuilderTarget>::Output { ... }
fn onpointermove<__Marker>(
self,
event_handler: impl EventHandlerValue<PointerData, __Marker>,
) -> <Self as AttributeBuilderTarget>::Output { ... }
fn onpointerup<__Marker>(
self,
event_handler: impl EventHandlerValue<PointerData, __Marker>,
) -> <Self as AttributeBuilderTarget>::Output { ... }
fn onpointercancel<__Marker>(
self,
event_handler: impl EventHandlerValue<PointerData, __Marker>,
) -> <Self as AttributeBuilderTarget>::Output { ... }
fn ongotpointercapture<__Marker>(
self,
event_handler: impl EventHandlerValue<PointerData, __Marker>,
) -> <Self as AttributeBuilderTarget>::Output { ... }
fn onlostpointercapture<__Marker>(
self,
event_handler: impl EventHandlerValue<PointerData, __Marker>,
) -> <Self as AttributeBuilderTarget>::Output { ... }
fn onpointerenter<__Marker>(
self,
event_handler: impl EventHandlerValue<PointerData, __Marker>,
) -> <Self as AttributeBuilderTarget>::Output { ... }
fn onpointerleave<__Marker>(
self,
event_handler: impl EventHandlerValue<PointerData, __Marker>,
) -> <Self as AttributeBuilderTarget>::Output { ... }
fn onpointerover<__Marker>(
self,
event_handler: impl EventHandlerValue<PointerData, __Marker>,
) -> <Self as AttributeBuilderTarget>::Output { ... }
fn onpointerout<__Marker>(
self,
event_handler: impl EventHandlerValue<PointerData, __Marker>,
) -> <Self as AttributeBuilderTarget>::Output { ... }
fn onauxclick<__Marker>(
self,
event_handler: impl EventHandlerValue<PointerData, __Marker>,
) -> <Self as AttributeBuilderTarget>::Output { ... }
fn onresize<__Marker>(
self,
event_handler: impl EventHandlerValue<ResizeData, __Marker>,
) -> <Self as AttributeBuilderTarget>::Output { ... }
fn onscroll<__Marker>(
self,
event_handler: impl EventHandlerValue<ScrollData, __Marker>,
) -> <Self as AttributeBuilderTarget>::Output { ... }
fn onscrollend<__Marker>(
self,
event_handler: impl EventHandlerValue<ScrollData, __Marker>,
) -> <Self as AttributeBuilderTarget>::Output { ... }
fn onselect<__Marker>(
self,
event_handler: impl EventHandlerValue<SelectionData, __Marker>,
) -> <Self as AttributeBuilderTarget>::Output { ... }
fn onselectstart<__Marker>(
self,
event_handler: impl EventHandlerValue<SelectionData, __Marker>,
) -> <Self as AttributeBuilderTarget>::Output { ... }
fn onselectionchange<__Marker>(
self,
event_handler: impl EventHandlerValue<SelectionData, __Marker>,
) -> <Self as AttributeBuilderTarget>::Output { ... }
fn ontoggle<__Marker>(
self,
event_handler: impl EventHandlerValue<ToggleData, __Marker>,
) -> <Self as AttributeBuilderTarget>::Output { ... }
fn onbeforetoggle<__Marker>(
self,
event_handler: impl EventHandlerValue<ToggleData, __Marker>,
) -> <Self as AttributeBuilderTarget>::Output { ... }
fn ontouchstart<__Marker>(
self,
event_handler: impl EventHandlerValue<TouchData, __Marker>,
) -> <Self as AttributeBuilderTarget>::Output { ... }
fn ontouchmove<__Marker>(
self,
event_handler: impl EventHandlerValue<TouchData, __Marker>,
) -> <Self as AttributeBuilderTarget>::Output { ... }
fn ontouchend<__Marker>(
self,
event_handler: impl EventHandlerValue<TouchData, __Marker>,
) -> <Self as AttributeBuilderTarget>::Output { ... }
fn ontouchcancel<__Marker>(
self,
event_handler: impl EventHandlerValue<TouchData, __Marker>,
) -> <Self as AttributeBuilderTarget>::Output { ... }
fn ontransitionend<__Marker>(
self,
event_handler: impl EventHandlerValue<TransitionData, __Marker>,
) -> <Self as AttributeBuilderTarget>::Output { ... }
fn onvisible<__Marker>(
self,
event_handler: impl EventHandlerValue<VisibleData, __Marker>,
) -> <Self as AttributeBuilderTarget>::Output { ... }
fn onwheel<__Marker>(
self,
event_handler: impl EventHandlerValue<WheelData, __Marker>,
) -> <Self as AttributeBuilderTarget>::Output { ... }
}Expand description
Event handler extension methods for typed HTML builders.
Provided Methods§
Sourcefn onanimationstart<__Marker>(
self,
event_handler: impl EventHandlerValue<AnimationData, __Marker>,
) -> <Self as AttributeBuilderTarget>::Output
fn onanimationstart<__Marker>( self, event_handler: impl EventHandlerValue<AnimationData, __Marker>, ) -> <Self as AttributeBuilderTarget>::Output
onanimationstart
General Event Handler Information
§Event Handlers
Event Handlers let you react to user input in your application. In Dioxus, event handlers accept a closure that is called when the event occurs:
use dioxus::prelude::*;
fn App() -> Element {
rsx! {
button {
// The `onclick` event accepts a closure with the signature `fn(Event)`
onclick: |event_data| println!("clicked! I got the event data: {event_data:?}"),
"Click me"
}
}
}§Event Lifetimes
Events take a closure with the 'static lifetime. This means that the closure can only access data that either exists for the entire lifetime of the application, or data that you move into the closure.
State in dioxus is copy which makes it very easy to move into 'static closures like event handlers:
let mut count = use_signal(|| 0);
rsx! {
button {
// Since we added the `move` keyword, the closure will move the `count` signal into the closure
onclick: move |_| {
// This will panic because the `count` signal is not in scope
count.set(count() + 1);
},
"Click me"
}
};If you need to access data that is not Copy, you may need to clone the data before you move it into the closure:
// String is not `Copy`
let string = "hello world".to_string();
rsx! {
button {
// The string only has one owner. We could move it into this closure, but since we want to use the string in other closures later, we will clone it instead
onclick: {
// Clone the string in a new block
let string = string.clone();
// Then move the cloned string into the closure
move |_| println!("{}", string)
},
"Print hello world"
}
button {
// We don't use the string after this closure, so we can just move it into the closure directly
onclick: move |_| println!("{}", string),
"Print hello world again"
}
};§Async Event Handlers
In addition to closures that return nothing, you can also use async closures to handle events. If you return an async block from an event handler, dioxus will automatically spawn it:
use dioxus::prelude::*;
fn App() -> Element {
rsx! {
button {
// The `onclick` event can also accept a closure that returns an async block
onclick: move |_| async move {
tokio::time::sleep(std::time::Duration::from_secs(1)).await;
println!("You clicked the button one second ago!");
},
"Click me"
}
}
}§Compiler errors you may run into while using event handlers
function requires argument type to outlive `'static`
Event handler in Dioxus need only access data that can last for the entire lifetime of the application. That generally means data that is moved into the closure. If you get this error, you may have forgotten to add move to your closure.
Broken component:
// We return an Element which can last as long as the component is on the screen
fn App() -> Element {
// Signals are `Copy` which makes them very easy to move into `'static` closures like event handlers
let state = use_signal(|| "hello world".to_string());
rsx! {
button {
// ❌ Without `move`, rust will try to borrow the `state` signal which fails because the state signal is dropped at the end of the function
onclick: |_| {
println!("You clicked the button! The state is: {state}");
},
"Click me"
}
}
// The state signal is dropped here, but the event handler still needs to access it
}Fixed component:
fn App() -> Element {
let state = use_signal(|| "hello world".to_string());
rsx! {
button {
// ✅ The `move` keyword tells rust it can move the `state` signal into the closure. Since the closure owns the signal state, it can read it even after the function returns
onclick: move |_| {
println!("You clicked the button! The state is: {state}");
},
"Click me"
}
}
}use of moved value: `your_value` value used here after move
Data in rust has a single owner. If you run into this error, you have likely tried to move data that isn’t Copy into two different closures. You can fix this issue by making your data Copy or calling clone on it before you move it into the closure.
Broken component:
// `MyComponent` accepts a string which cannot be copied implicitly
#[component]
fn MyComponent(string: String) -> Element {
rsx! {
button {
// ❌ We are moving the string into the onclick handler which means we can't access it elsewhere
onclick: move |_| {
println!("{string}");
},
"Print hello world"
}
button {
// ❌ Since we already moved the string, we can't move it into the onclick handler again. This will cause a compiler error
onclick: move |_| {
println!("{string}");
},
"Print hello world again"
}
}
}You can fix this issue by either:
- Making your data
CopywithReadSignal:
// `MyComponent` accepts `ReadSignal<String>` which implements `Copy`
#[component]
fn MyComponent(string: ReadSignal<String>) -> Element {
rsx! {
button {
// ✅ Because the `string` signal is `Copy`, we can copy it into the closure while still having access to it elsewhere
onclick: move |_| println!("{}", string),
"Print hello world"
}
button {
// ✅ Since `string` is `Copy`, we can move it into the onclick handler again
onclick: move |_| println!("{}", string),
"Print hello world again"
}
}
}- Calling
cloneon your data before you move it into the closure:
// `MyComponent` accepts a string which doesn't implement `Copy`
#[component]
fn MyComponent(string: String) -> Element {
rsx! {
button {
// ✅ The string only has one owner. We could move it into this closure, but since we want to use the string in other closures later, we will clone it instead
onclick: {
// Clone the string in a new block
let string = string.clone();
// Then move the cloned string into the closure
move |_| println!("{}", string)
},
"Print hello world"
}
button {
// ✅ We don't use the string after this closure, so we can just move it into the closure directly
onclick: move |_| println!("{}", string),
"Print hello world again"
}
}
}Sourcefn onanimationend<__Marker>(
self,
event_handler: impl EventHandlerValue<AnimationData, __Marker>,
) -> <Self as AttributeBuilderTarget>::Output
fn onanimationend<__Marker>( self, event_handler: impl EventHandlerValue<AnimationData, __Marker>, ) -> <Self as AttributeBuilderTarget>::Output
onanimationend
General Event Handler Information
§Event Handlers
Event Handlers let you react to user input in your application. In Dioxus, event handlers accept a closure that is called when the event occurs:
use dioxus::prelude::*;
fn App() -> Element {
rsx! {
button {
// The `onclick` event accepts a closure with the signature `fn(Event)`
onclick: |event_data| println!("clicked! I got the event data: {event_data:?}"),
"Click me"
}
}
}§Event Lifetimes
Events take a closure with the 'static lifetime. This means that the closure can only access data that either exists for the entire lifetime of the application, or data that you move into the closure.
State in dioxus is copy which makes it very easy to move into 'static closures like event handlers:
let mut count = use_signal(|| 0);
rsx! {
button {
// Since we added the `move` keyword, the closure will move the `count` signal into the closure
onclick: move |_| {
// This will panic because the `count` signal is not in scope
count.set(count() + 1);
},
"Click me"
}
};If you need to access data that is not Copy, you may need to clone the data before you move it into the closure:
// String is not `Copy`
let string = "hello world".to_string();
rsx! {
button {
// The string only has one owner. We could move it into this closure, but since we want to use the string in other closures later, we will clone it instead
onclick: {
// Clone the string in a new block
let string = string.clone();
// Then move the cloned string into the closure
move |_| println!("{}", string)
},
"Print hello world"
}
button {
// We don't use the string after this closure, so we can just move it into the closure directly
onclick: move |_| println!("{}", string),
"Print hello world again"
}
};§Async Event Handlers
In addition to closures that return nothing, you can also use async closures to handle events. If you return an async block from an event handler, dioxus will automatically spawn it:
use dioxus::prelude::*;
fn App() -> Element {
rsx! {
button {
// The `onclick` event can also accept a closure that returns an async block
onclick: move |_| async move {
tokio::time::sleep(std::time::Duration::from_secs(1)).await;
println!("You clicked the button one second ago!");
},
"Click me"
}
}
}§Compiler errors you may run into while using event handlers
function requires argument type to outlive `'static`
Event handler in Dioxus need only access data that can last for the entire lifetime of the application. That generally means data that is moved into the closure. If you get this error, you may have forgotten to add move to your closure.
Broken component:
// We return an Element which can last as long as the component is on the screen
fn App() -> Element {
// Signals are `Copy` which makes them very easy to move into `'static` closures like event handlers
let state = use_signal(|| "hello world".to_string());
rsx! {
button {
// ❌ Without `move`, rust will try to borrow the `state` signal which fails because the state signal is dropped at the end of the function
onclick: |_| {
println!("You clicked the button! The state is: {state}");
},
"Click me"
}
}
// The state signal is dropped here, but the event handler still needs to access it
}Fixed component:
fn App() -> Element {
let state = use_signal(|| "hello world".to_string());
rsx! {
button {
// ✅ The `move` keyword tells rust it can move the `state` signal into the closure. Since the closure owns the signal state, it can read it even after the function returns
onclick: move |_| {
println!("You clicked the button! The state is: {state}");
},
"Click me"
}
}
}use of moved value: `your_value` value used here after move
Data in rust has a single owner. If you run into this error, you have likely tried to move data that isn’t Copy into two different closures. You can fix this issue by making your data Copy or calling clone on it before you move it into the closure.
Broken component:
// `MyComponent` accepts a string which cannot be copied implicitly
#[component]
fn MyComponent(string: String) -> Element {
rsx! {
button {
// ❌ We are moving the string into the onclick handler which means we can't access it elsewhere
onclick: move |_| {
println!("{string}");
},
"Print hello world"
}
button {
// ❌ Since we already moved the string, we can't move it into the onclick handler again. This will cause a compiler error
onclick: move |_| {
println!("{string}");
},
"Print hello world again"
}
}
}You can fix this issue by either:
- Making your data
CopywithReadSignal:
// `MyComponent` accepts `ReadSignal<String>` which implements `Copy`
#[component]
fn MyComponent(string: ReadSignal<String>) -> Element {
rsx! {
button {
// ✅ Because the `string` signal is `Copy`, we can copy it into the closure while still having access to it elsewhere
onclick: move |_| println!("{}", string),
"Print hello world"
}
button {
// ✅ Since `string` is `Copy`, we can move it into the onclick handler again
onclick: move |_| println!("{}", string),
"Print hello world again"
}
}
}- Calling
cloneon your data before you move it into the closure:
// `MyComponent` accepts a string which doesn't implement `Copy`
#[component]
fn MyComponent(string: String) -> Element {
rsx! {
button {
// ✅ The string only has one owner. We could move it into this closure, but since we want to use the string in other closures later, we will clone it instead
onclick: {
// Clone the string in a new block
let string = string.clone();
// Then move the cloned string into the closure
move |_| println!("{}", string)
},
"Print hello world"
}
button {
// ✅ We don't use the string after this closure, so we can just move it into the closure directly
onclick: move |_| println!("{}", string),
"Print hello world again"
}
}
}Sourcefn onanimationiteration<__Marker>(
self,
event_handler: impl EventHandlerValue<AnimationData, __Marker>,
) -> <Self as AttributeBuilderTarget>::Output
fn onanimationiteration<__Marker>( self, event_handler: impl EventHandlerValue<AnimationData, __Marker>, ) -> <Self as AttributeBuilderTarget>::Output
onanimationiteration
General Event Handler Information
§Event Handlers
Event Handlers let you react to user input in your application. In Dioxus, event handlers accept a closure that is called when the event occurs:
use dioxus::prelude::*;
fn App() -> Element {
rsx! {
button {
// The `onclick` event accepts a closure with the signature `fn(Event)`
onclick: |event_data| println!("clicked! I got the event data: {event_data:?}"),
"Click me"
}
}
}§Event Lifetimes
Events take a closure with the 'static lifetime. This means that the closure can only access data that either exists for the entire lifetime of the application, or data that you move into the closure.
State in dioxus is copy which makes it very easy to move into 'static closures like event handlers:
let mut count = use_signal(|| 0);
rsx! {
button {
// Since we added the `move` keyword, the closure will move the `count` signal into the closure
onclick: move |_| {
// This will panic because the `count` signal is not in scope
count.set(count() + 1);
},
"Click me"
}
};If you need to access data that is not Copy, you may need to clone the data before you move it into the closure:
// String is not `Copy`
let string = "hello world".to_string();
rsx! {
button {
// The string only has one owner. We could move it into this closure, but since we want to use the string in other closures later, we will clone it instead
onclick: {
// Clone the string in a new block
let string = string.clone();
// Then move the cloned string into the closure
move |_| println!("{}", string)
},
"Print hello world"
}
button {
// We don't use the string after this closure, so we can just move it into the closure directly
onclick: move |_| println!("{}", string),
"Print hello world again"
}
};§Async Event Handlers
In addition to closures that return nothing, you can also use async closures to handle events. If you return an async block from an event handler, dioxus will automatically spawn it:
use dioxus::prelude::*;
fn App() -> Element {
rsx! {
button {
// The `onclick` event can also accept a closure that returns an async block
onclick: move |_| async move {
tokio::time::sleep(std::time::Duration::from_secs(1)).await;
println!("You clicked the button one second ago!");
},
"Click me"
}
}
}§Compiler errors you may run into while using event handlers
function requires argument type to outlive `'static`
Event handler in Dioxus need only access data that can last for the entire lifetime of the application. That generally means data that is moved into the closure. If you get this error, you may have forgotten to add move to your closure.
Broken component:
// We return an Element which can last as long as the component is on the screen
fn App() -> Element {
// Signals are `Copy` which makes them very easy to move into `'static` closures like event handlers
let state = use_signal(|| "hello world".to_string());
rsx! {
button {
// ❌ Without `move`, rust will try to borrow the `state` signal which fails because the state signal is dropped at the end of the function
onclick: |_| {
println!("You clicked the button! The state is: {state}");
},
"Click me"
}
}
// The state signal is dropped here, but the event handler still needs to access it
}Fixed component:
fn App() -> Element {
let state = use_signal(|| "hello world".to_string());
rsx! {
button {
// ✅ The `move` keyword tells rust it can move the `state` signal into the closure. Since the closure owns the signal state, it can read it even after the function returns
onclick: move |_| {
println!("You clicked the button! The state is: {state}");
},
"Click me"
}
}
}use of moved value: `your_value` value used here after move
Data in rust has a single owner. If you run into this error, you have likely tried to move data that isn’t Copy into two different closures. You can fix this issue by making your data Copy or calling clone on it before you move it into the closure.
Broken component:
// `MyComponent` accepts a string which cannot be copied implicitly
#[component]
fn MyComponent(string: String) -> Element {
rsx! {
button {
// ❌ We are moving the string into the onclick handler which means we can't access it elsewhere
onclick: move |_| {
println!("{string}");
},
"Print hello world"
}
button {
// ❌ Since we already moved the string, we can't move it into the onclick handler again. This will cause a compiler error
onclick: move |_| {
println!("{string}");
},
"Print hello world again"
}
}
}You can fix this issue by either:
- Making your data
CopywithReadSignal:
// `MyComponent` accepts `ReadSignal<String>` which implements `Copy`
#[component]
fn MyComponent(string: ReadSignal<String>) -> Element {
rsx! {
button {
// ✅ Because the `string` signal is `Copy`, we can copy it into the closure while still having access to it elsewhere
onclick: move |_| println!("{}", string),
"Print hello world"
}
button {
// ✅ Since `string` is `Copy`, we can move it into the onclick handler again
onclick: move |_| println!("{}", string),
"Print hello world again"
}
}
}- Calling
cloneon your data before you move it into the closure:
// `MyComponent` accepts a string which doesn't implement `Copy`
#[component]
fn MyComponent(string: String) -> Element {
rsx! {
button {
// ✅ The string only has one owner. We could move it into this closure, but since we want to use the string in other closures later, we will clone it instead
onclick: {
// Clone the string in a new block
let string = string.clone();
// Then move the cloned string into the closure
move |_| println!("{}", string)
},
"Print hello world"
}
button {
// ✅ We don't use the string after this closure, so we can just move it into the closure directly
onclick: move |_| println!("{}", string),
"Print hello world again"
}
}
}Sourcefn onbeforeinput<__Marker>(
self,
event_handler: impl EventHandlerValue<BeforeInputData, __Marker>,
) -> <Self as AttributeBuilderTarget>::Output
fn onbeforeinput<__Marker>( self, event_handler: impl EventHandlerValue<BeforeInputData, __Marker>, ) -> <Self as AttributeBuilderTarget>::Output
onbeforeinput
The beforeinput event fires before an editable element (an <input>,
<textarea>, or any element with contenteditable="true") is about to
be modified. Unlike oninput, this event is cancellable — calling
event.prevent_default() from the handler blocks the change.
Use BeforeInputData::input_type to identify the kind of mutation
(e.g. InputType::InsertText, InputType::DeleteContentBackward,
InputType::InsertFromPaste) and BeforeInputData::data to read
the text being inserted.
use dioxus::prelude::*;
fn App() -> Element {
rsx! {
input {
onbeforeinput: move |event| {
// Block any attempt to insert a digit
if event.data.input_type() == InputType::InsertText
&& event.data.data().is_some_and(|d| d.chars().any(|c| c.is_ascii_digit()))
{
event.prevent_default();
}
}
}
}
}See https://developer.mozilla.org/en-US/docs/Web/API/Element/beforeinput_event.
General Event Handler Information
§Event Handlers
Event Handlers let you react to user input in your application. In Dioxus, event handlers accept a closure that is called when the event occurs:
use dioxus::prelude::*;
fn App() -> Element {
rsx! {
button {
// The `onclick` event accepts a closure with the signature `fn(Event)`
onclick: |event_data| println!("clicked! I got the event data: {event_data:?}"),
"Click me"
}
}
}§Event Lifetimes
Events take a closure with the 'static lifetime. This means that the closure can only access data that either exists for the entire lifetime of the application, or data that you move into the closure.
State in dioxus is copy which makes it very easy to move into 'static closures like event handlers:
let mut count = use_signal(|| 0);
rsx! {
button {
// Since we added the `move` keyword, the closure will move the `count` signal into the closure
onclick: move |_| {
// This will panic because the `count` signal is not in scope
count.set(count() + 1);
},
"Click me"
}
};If you need to access data that is not Copy, you may need to clone the data before you move it into the closure:
// String is not `Copy`
let string = "hello world".to_string();
rsx! {
button {
// The string only has one owner. We could move it into this closure, but since we want to use the string in other closures later, we will clone it instead
onclick: {
// Clone the string in a new block
let string = string.clone();
// Then move the cloned string into the closure
move |_| println!("{}", string)
},
"Print hello world"
}
button {
// We don't use the string after this closure, so we can just move it into the closure directly
onclick: move |_| println!("{}", string),
"Print hello world again"
}
};§Async Event Handlers
In addition to closures that return nothing, you can also use async closures to handle events. If you return an async block from an event handler, dioxus will automatically spawn it:
use dioxus::prelude::*;
fn App() -> Element {
rsx! {
button {
// The `onclick` event can also accept a closure that returns an async block
onclick: move |_| async move {
tokio::time::sleep(std::time::Duration::from_secs(1)).await;
println!("You clicked the button one second ago!");
},
"Click me"
}
}
}§Compiler errors you may run into while using event handlers
function requires argument type to outlive `'static`
Event handler in Dioxus need only access data that can last for the entire lifetime of the application. That generally means data that is moved into the closure. If you get this error, you may have forgotten to add move to your closure.
Broken component:
// We return an Element which can last as long as the component is on the screen
fn App() -> Element {
// Signals are `Copy` which makes them very easy to move into `'static` closures like event handlers
let state = use_signal(|| "hello world".to_string());
rsx! {
button {
// ❌ Without `move`, rust will try to borrow the `state` signal which fails because the state signal is dropped at the end of the function
onclick: |_| {
println!("You clicked the button! The state is: {state}");
},
"Click me"
}
}
// The state signal is dropped here, but the event handler still needs to access it
}Fixed component:
fn App() -> Element {
let state = use_signal(|| "hello world".to_string());
rsx! {
button {
// ✅ The `move` keyword tells rust it can move the `state` signal into the closure. Since the closure owns the signal state, it can read it even after the function returns
onclick: move |_| {
println!("You clicked the button! The state is: {state}");
},
"Click me"
}
}
}use of moved value: `your_value` value used here after move
Data in rust has a single owner. If you run into this error, you have likely tried to move data that isn’t Copy into two different closures. You can fix this issue by making your data Copy or calling clone on it before you move it into the closure.
Broken component:
// `MyComponent` accepts a string which cannot be copied implicitly
#[component]
fn MyComponent(string: String) -> Element {
rsx! {
button {
// ❌ We are moving the string into the onclick handler which means we can't access it elsewhere
onclick: move |_| {
println!("{string}");
},
"Print hello world"
}
button {
// ❌ Since we already moved the string, we can't move it into the onclick handler again. This will cause a compiler error
onclick: move |_| {
println!("{string}");
},
"Print hello world again"
}
}
}You can fix this issue by either:
- Making your data
CopywithReadSignal:
// `MyComponent` accepts `ReadSignal<String>` which implements `Copy`
#[component]
fn MyComponent(string: ReadSignal<String>) -> Element {
rsx! {
button {
// ✅ Because the `string` signal is `Copy`, we can copy it into the closure while still having access to it elsewhere
onclick: move |_| println!("{}", string),
"Print hello world"
}
button {
// ✅ Since `string` is `Copy`, we can move it into the onclick handler again
onclick: move |_| println!("{}", string),
"Print hello world again"
}
}
}- Calling
cloneon your data before you move it into the closure:
// `MyComponent` accepts a string which doesn't implement `Copy`
#[component]
fn MyComponent(string: String) -> Element {
rsx! {
button {
// ✅ The string only has one owner. We could move it into this closure, but since we want to use the string in other closures later, we will clone it instead
onclick: {
// Clone the string in a new block
let string = string.clone();
// Then move the cloned string into the closure
move |_| println!("{}", string)
},
"Print hello world"
}
button {
// ✅ We don't use the string after this closure, so we can just move it into the closure directly
onclick: move |_| println!("{}", string),
"Print hello world again"
}
}
}Sourcefn oncancel<__Marker>(
self,
event_handler: impl EventHandlerValue<CancelData, __Marker>,
) -> <Self as AttributeBuilderTarget>::Output
fn oncancel<__Marker>( self, event_handler: impl EventHandlerValue<CancelData, __Marker>, ) -> <Self as AttributeBuilderTarget>::Output
oncancel
General Event Handler Information
§Event Handlers
Event Handlers let you react to user input in your application. In Dioxus, event handlers accept a closure that is called when the event occurs:
use dioxus::prelude::*;
fn App() -> Element {
rsx! {
button {
// The `onclick` event accepts a closure with the signature `fn(Event)`
onclick: |event_data| println!("clicked! I got the event data: {event_data:?}"),
"Click me"
}
}
}§Event Lifetimes
Events take a closure with the 'static lifetime. This means that the closure can only access data that either exists for the entire lifetime of the application, or data that you move into the closure.
State in dioxus is copy which makes it very easy to move into 'static closures like event handlers:
let mut count = use_signal(|| 0);
rsx! {
button {
// Since we added the `move` keyword, the closure will move the `count` signal into the closure
onclick: move |_| {
// This will panic because the `count` signal is not in scope
count.set(count() + 1);
},
"Click me"
}
};If you need to access data that is not Copy, you may need to clone the data before you move it into the closure:
// String is not `Copy`
let string = "hello world".to_string();
rsx! {
button {
// The string only has one owner. We could move it into this closure, but since we want to use the string in other closures later, we will clone it instead
onclick: {
// Clone the string in a new block
let string = string.clone();
// Then move the cloned string into the closure
move |_| println!("{}", string)
},
"Print hello world"
}
button {
// We don't use the string after this closure, so we can just move it into the closure directly
onclick: move |_| println!("{}", string),
"Print hello world again"
}
};§Async Event Handlers
In addition to closures that return nothing, you can also use async closures to handle events. If you return an async block from an event handler, dioxus will automatically spawn it:
use dioxus::prelude::*;
fn App() -> Element {
rsx! {
button {
// The `onclick` event can also accept a closure that returns an async block
onclick: move |_| async move {
tokio::time::sleep(std::time::Duration::from_secs(1)).await;
println!("You clicked the button one second ago!");
},
"Click me"
}
}
}§Compiler errors you may run into while using event handlers
function requires argument type to outlive `'static`
Event handler in Dioxus need only access data that can last for the entire lifetime of the application. That generally means data that is moved into the closure. If you get this error, you may have forgotten to add move to your closure.
Broken component:
// We return an Element which can last as long as the component is on the screen
fn App() -> Element {
// Signals are `Copy` which makes them very easy to move into `'static` closures like event handlers
let state = use_signal(|| "hello world".to_string());
rsx! {
button {
// ❌ Without `move`, rust will try to borrow the `state` signal which fails because the state signal is dropped at the end of the function
onclick: |_| {
println!("You clicked the button! The state is: {state}");
},
"Click me"
}
}
// The state signal is dropped here, but the event handler still needs to access it
}Fixed component:
fn App() -> Element {
let state = use_signal(|| "hello world".to_string());
rsx! {
button {
// ✅ The `move` keyword tells rust it can move the `state` signal into the closure. Since the closure owns the signal state, it can read it even after the function returns
onclick: move |_| {
println!("You clicked the button! The state is: {state}");
},
"Click me"
}
}
}use of moved value: `your_value` value used here after move
Data in rust has a single owner. If you run into this error, you have likely tried to move data that isn’t Copy into two different closures. You can fix this issue by making your data Copy or calling clone on it before you move it into the closure.
Broken component:
// `MyComponent` accepts a string which cannot be copied implicitly
#[component]
fn MyComponent(string: String) -> Element {
rsx! {
button {
// ❌ We are moving the string into the onclick handler which means we can't access it elsewhere
onclick: move |_| {
println!("{string}");
},
"Print hello world"
}
button {
// ❌ Since we already moved the string, we can't move it into the onclick handler again. This will cause a compiler error
onclick: move |_| {
println!("{string}");
},
"Print hello world again"
}
}
}You can fix this issue by either:
- Making your data
CopywithReadSignal:
// `MyComponent` accepts `ReadSignal<String>` which implements `Copy`
#[component]
fn MyComponent(string: ReadSignal<String>) -> Element {
rsx! {
button {
// ✅ Because the `string` signal is `Copy`, we can copy it into the closure while still having access to it elsewhere
onclick: move |_| println!("{}", string),
"Print hello world"
}
button {
// ✅ Since `string` is `Copy`, we can move it into the onclick handler again
onclick: move |_| println!("{}", string),
"Print hello world again"
}
}
}- Calling
cloneon your data before you move it into the closure:
// `MyComponent` accepts a string which doesn't implement `Copy`
#[component]
fn MyComponent(string: String) -> Element {
rsx! {
button {
// ✅ The string only has one owner. We could move it into this closure, but since we want to use the string in other closures later, we will clone it instead
onclick: {
// Clone the string in a new block
let string = string.clone();
// Then move the cloned string into the closure
move |_| println!("{}", string)
},
"Print hello world"
}
button {
// ✅ We don't use the string after this closure, so we can just move it into the closure directly
onclick: move |_| println!("{}", string),
"Print hello world again"
}
}
}Sourcefn oncopy<__Marker>(
self,
event_handler: impl EventHandlerValue<ClipboardData, __Marker>,
) -> <Self as AttributeBuilderTarget>::Output
fn oncopy<__Marker>( self, event_handler: impl EventHandlerValue<ClipboardData, __Marker>, ) -> <Self as AttributeBuilderTarget>::Output
oncopy
General Event Handler Information
§Event Handlers
Event Handlers let you react to user input in your application. In Dioxus, event handlers accept a closure that is called when the event occurs:
use dioxus::prelude::*;
fn App() -> Element {
rsx! {
button {
// The `onclick` event accepts a closure with the signature `fn(Event)`
onclick: |event_data| println!("clicked! I got the event data: {event_data:?}"),
"Click me"
}
}
}§Event Lifetimes
Events take a closure with the 'static lifetime. This means that the closure can only access data that either exists for the entire lifetime of the application, or data that you move into the closure.
State in dioxus is copy which makes it very easy to move into 'static closures like event handlers:
let mut count = use_signal(|| 0);
rsx! {
button {
// Since we added the `move` keyword, the closure will move the `count` signal into the closure
onclick: move |_| {
// This will panic because the `count` signal is not in scope
count.set(count() + 1);
},
"Click me"
}
};If you need to access data that is not Copy, you may need to clone the data before you move it into the closure:
// String is not `Copy`
let string = "hello world".to_string();
rsx! {
button {
// The string only has one owner. We could move it into this closure, but since we want to use the string in other closures later, we will clone it instead
onclick: {
// Clone the string in a new block
let string = string.clone();
// Then move the cloned string into the closure
move |_| println!("{}", string)
},
"Print hello world"
}
button {
// We don't use the string after this closure, so we can just move it into the closure directly
onclick: move |_| println!("{}", string),
"Print hello world again"
}
};§Async Event Handlers
In addition to closures that return nothing, you can also use async closures to handle events. If you return an async block from an event handler, dioxus will automatically spawn it:
use dioxus::prelude::*;
fn App() -> Element {
rsx! {
button {
// The `onclick` event can also accept a closure that returns an async block
onclick: move |_| async move {
tokio::time::sleep(std::time::Duration::from_secs(1)).await;
println!("You clicked the button one second ago!");
},
"Click me"
}
}
}§Compiler errors you may run into while using event handlers
function requires argument type to outlive `'static`
Event handler in Dioxus need only access data that can last for the entire lifetime of the application. That generally means data that is moved into the closure. If you get this error, you may have forgotten to add move to your closure.
Broken component:
// We return an Element which can last as long as the component is on the screen
fn App() -> Element {
// Signals are `Copy` which makes them very easy to move into `'static` closures like event handlers
let state = use_signal(|| "hello world".to_string());
rsx! {
button {
// ❌ Without `move`, rust will try to borrow the `state` signal which fails because the state signal is dropped at the end of the function
onclick: |_| {
println!("You clicked the button! The state is: {state}");
},
"Click me"
}
}
// The state signal is dropped here, but the event handler still needs to access it
}Fixed component:
fn App() -> Element {
let state = use_signal(|| "hello world".to_string());
rsx! {
button {
// ✅ The `move` keyword tells rust it can move the `state` signal into the closure. Since the closure owns the signal state, it can read it even after the function returns
onclick: move |_| {
println!("You clicked the button! The state is: {state}");
},
"Click me"
}
}
}use of moved value: `your_value` value used here after move
Data in rust has a single owner. If you run into this error, you have likely tried to move data that isn’t Copy into two different closures. You can fix this issue by making your data Copy or calling clone on it before you move it into the closure.
Broken component:
// `MyComponent` accepts a string which cannot be copied implicitly
#[component]
fn MyComponent(string: String) -> Element {
rsx! {
button {
// ❌ We are moving the string into the onclick handler which means we can't access it elsewhere
onclick: move |_| {
println!("{string}");
},
"Print hello world"
}
button {
// ❌ Since we already moved the string, we can't move it into the onclick handler again. This will cause a compiler error
onclick: move |_| {
println!("{string}");
},
"Print hello world again"
}
}
}You can fix this issue by either:
- Making your data
CopywithReadSignal:
// `MyComponent` accepts `ReadSignal<String>` which implements `Copy`
#[component]
fn MyComponent(string: ReadSignal<String>) -> Element {
rsx! {
button {
// ✅ Because the `string` signal is `Copy`, we can copy it into the closure while still having access to it elsewhere
onclick: move |_| println!("{}", string),
"Print hello world"
}
button {
// ✅ Since `string` is `Copy`, we can move it into the onclick handler again
onclick: move |_| println!("{}", string),
"Print hello world again"
}
}
}- Calling
cloneon your data before you move it into the closure:
// `MyComponent` accepts a string which doesn't implement `Copy`
#[component]
fn MyComponent(string: String) -> Element {
rsx! {
button {
// ✅ The string only has one owner. We could move it into this closure, but since we want to use the string in other closures later, we will clone it instead
onclick: {
// Clone the string in a new block
let string = string.clone();
// Then move the cloned string into the closure
move |_| println!("{}", string)
},
"Print hello world"
}
button {
// ✅ We don't use the string after this closure, so we can just move it into the closure directly
onclick: move |_| println!("{}", string),
"Print hello world again"
}
}
}Sourcefn oncut<__Marker>(
self,
event_handler: impl EventHandlerValue<ClipboardData, __Marker>,
) -> <Self as AttributeBuilderTarget>::Output
fn oncut<__Marker>( self, event_handler: impl EventHandlerValue<ClipboardData, __Marker>, ) -> <Self as AttributeBuilderTarget>::Output
oncut
General Event Handler Information
§Event Handlers
Event Handlers let you react to user input in your application. In Dioxus, event handlers accept a closure that is called when the event occurs:
use dioxus::prelude::*;
fn App() -> Element {
rsx! {
button {
// The `onclick` event accepts a closure with the signature `fn(Event)`
onclick: |event_data| println!("clicked! I got the event data: {event_data:?}"),
"Click me"
}
}
}§Event Lifetimes
Events take a closure with the 'static lifetime. This means that the closure can only access data that either exists for the entire lifetime of the application, or data that you move into the closure.
State in dioxus is copy which makes it very easy to move into 'static closures like event handlers:
let mut count = use_signal(|| 0);
rsx! {
button {
// Since we added the `move` keyword, the closure will move the `count` signal into the closure
onclick: move |_| {
// This will panic because the `count` signal is not in scope
count.set(count() + 1);
},
"Click me"
}
};If you need to access data that is not Copy, you may need to clone the data before you move it into the closure:
// String is not `Copy`
let string = "hello world".to_string();
rsx! {
button {
// The string only has one owner. We could move it into this closure, but since we want to use the string in other closures later, we will clone it instead
onclick: {
// Clone the string in a new block
let string = string.clone();
// Then move the cloned string into the closure
move |_| println!("{}", string)
},
"Print hello world"
}
button {
// We don't use the string after this closure, so we can just move it into the closure directly
onclick: move |_| println!("{}", string),
"Print hello world again"
}
};§Async Event Handlers
In addition to closures that return nothing, you can also use async closures to handle events. If you return an async block from an event handler, dioxus will automatically spawn it:
use dioxus::prelude::*;
fn App() -> Element {
rsx! {
button {
// The `onclick` event can also accept a closure that returns an async block
onclick: move |_| async move {
tokio::time::sleep(std::time::Duration::from_secs(1)).await;
println!("You clicked the button one second ago!");
},
"Click me"
}
}
}§Compiler errors you may run into while using event handlers
function requires argument type to outlive `'static`
Event handler in Dioxus need only access data that can last for the entire lifetime of the application. That generally means data that is moved into the closure. If you get this error, you may have forgotten to add move to your closure.
Broken component:
// We return an Element which can last as long as the component is on the screen
fn App() -> Element {
// Signals are `Copy` which makes them very easy to move into `'static` closures like event handlers
let state = use_signal(|| "hello world".to_string());
rsx! {
button {
// ❌ Without `move`, rust will try to borrow the `state` signal which fails because the state signal is dropped at the end of the function
onclick: |_| {
println!("You clicked the button! The state is: {state}");
},
"Click me"
}
}
// The state signal is dropped here, but the event handler still needs to access it
}Fixed component:
fn App() -> Element {
let state = use_signal(|| "hello world".to_string());
rsx! {
button {
// ✅ The `move` keyword tells rust it can move the `state` signal into the closure. Since the closure owns the signal state, it can read it even after the function returns
onclick: move |_| {
println!("You clicked the button! The state is: {state}");
},
"Click me"
}
}
}use of moved value: `your_value` value used here after move
Data in rust has a single owner. If you run into this error, you have likely tried to move data that isn’t Copy into two different closures. You can fix this issue by making your data Copy or calling clone on it before you move it into the closure.
Broken component:
// `MyComponent` accepts a string which cannot be copied implicitly
#[component]
fn MyComponent(string: String) -> Element {
rsx! {
button {
// ❌ We are moving the string into the onclick handler which means we can't access it elsewhere
onclick: move |_| {
println!("{string}");
},
"Print hello world"
}
button {
// ❌ Since we already moved the string, we can't move it into the onclick handler again. This will cause a compiler error
onclick: move |_| {
println!("{string}");
},
"Print hello world again"
}
}
}You can fix this issue by either:
- Making your data
CopywithReadSignal:
// `MyComponent` accepts `ReadSignal<String>` which implements `Copy`
#[component]
fn MyComponent(string: ReadSignal<String>) -> Element {
rsx! {
button {
// ✅ Because the `string` signal is `Copy`, we can copy it into the closure while still having access to it elsewhere
onclick: move |_| println!("{}", string),
"Print hello world"
}
button {
// ✅ Since `string` is `Copy`, we can move it into the onclick handler again
onclick: move |_| println!("{}", string),
"Print hello world again"
}
}
}- Calling
cloneon your data before you move it into the closure:
// `MyComponent` accepts a string which doesn't implement `Copy`
#[component]
fn MyComponent(string: String) -> Element {
rsx! {
button {
// ✅ The string only has one owner. We could move it into this closure, but since we want to use the string in other closures later, we will clone it instead
onclick: {
// Clone the string in a new block
let string = string.clone();
// Then move the cloned string into the closure
move |_| println!("{}", string)
},
"Print hello world"
}
button {
// ✅ We don't use the string after this closure, so we can just move it into the closure directly
onclick: move |_| println!("{}", string),
"Print hello world again"
}
}
}Sourcefn onpaste<__Marker>(
self,
event_handler: impl EventHandlerValue<ClipboardData, __Marker>,
) -> <Self as AttributeBuilderTarget>::Output
fn onpaste<__Marker>( self, event_handler: impl EventHandlerValue<ClipboardData, __Marker>, ) -> <Self as AttributeBuilderTarget>::Output
onpaste
General Event Handler Information
§Event Handlers
Event Handlers let you react to user input in your application. In Dioxus, event handlers accept a closure that is called when the event occurs:
use dioxus::prelude::*;
fn App() -> Element {
rsx! {
button {
// The `onclick` event accepts a closure with the signature `fn(Event)`
onclick: |event_data| println!("clicked! I got the event data: {event_data:?}"),
"Click me"
}
}
}§Event Lifetimes
Events take a closure with the 'static lifetime. This means that the closure can only access data that either exists for the entire lifetime of the application, or data that you move into the closure.
State in dioxus is copy which makes it very easy to move into 'static closures like event handlers:
let mut count = use_signal(|| 0);
rsx! {
button {
// Since we added the `move` keyword, the closure will move the `count` signal into the closure
onclick: move |_| {
// This will panic because the `count` signal is not in scope
count.set(count() + 1);
},
"Click me"
}
};If you need to access data that is not Copy, you may need to clone the data before you move it into the closure:
// String is not `Copy`
let string = "hello world".to_string();
rsx! {
button {
// The string only has one owner. We could move it into this closure, but since we want to use the string in other closures later, we will clone it instead
onclick: {
// Clone the string in a new block
let string = string.clone();
// Then move the cloned string into the closure
move |_| println!("{}", string)
},
"Print hello world"
}
button {
// We don't use the string after this closure, so we can just move it into the closure directly
onclick: move |_| println!("{}", string),
"Print hello world again"
}
};§Async Event Handlers
In addition to closures that return nothing, you can also use async closures to handle events. If you return an async block from an event handler, dioxus will automatically spawn it:
use dioxus::prelude::*;
fn App() -> Element {
rsx! {
button {
// The `onclick` event can also accept a closure that returns an async block
onclick: move |_| async move {
tokio::time::sleep(std::time::Duration::from_secs(1)).await;
println!("You clicked the button one second ago!");
},
"Click me"
}
}
}§Compiler errors you may run into while using event handlers
function requires argument type to outlive `'static`
Event handler in Dioxus need only access data that can last for the entire lifetime of the application. That generally means data that is moved into the closure. If you get this error, you may have forgotten to add move to your closure.
Broken component:
// We return an Element which can last as long as the component is on the screen
fn App() -> Element {
// Signals are `Copy` which makes them very easy to move into `'static` closures like event handlers
let state = use_signal(|| "hello world".to_string());
rsx! {
button {
// ❌ Without `move`, rust will try to borrow the `state` signal which fails because the state signal is dropped at the end of the function
onclick: |_| {
println!("You clicked the button! The state is: {state}");
},
"Click me"
}
}
// The state signal is dropped here, but the event handler still needs to access it
}Fixed component:
fn App() -> Element {
let state = use_signal(|| "hello world".to_string());
rsx! {
button {
// ✅ The `move` keyword tells rust it can move the `state` signal into the closure. Since the closure owns the signal state, it can read it even after the function returns
onclick: move |_| {
println!("You clicked the button! The state is: {state}");
},
"Click me"
}
}
}use of moved value: `your_value` value used here after move
Data in rust has a single owner. If you run into this error, you have likely tried to move data that isn’t Copy into two different closures. You can fix this issue by making your data Copy or calling clone on it before you move it into the closure.
Broken component:
// `MyComponent` accepts a string which cannot be copied implicitly
#[component]
fn MyComponent(string: String) -> Element {
rsx! {
button {
// ❌ We are moving the string into the onclick handler which means we can't access it elsewhere
onclick: move |_| {
println!("{string}");
},
"Print hello world"
}
button {
// ❌ Since we already moved the string, we can't move it into the onclick handler again. This will cause a compiler error
onclick: move |_| {
println!("{string}");
},
"Print hello world again"
}
}
}You can fix this issue by either:
- Making your data
CopywithReadSignal:
// `MyComponent` accepts `ReadSignal<String>` which implements `Copy`
#[component]
fn MyComponent(string: ReadSignal<String>) -> Element {
rsx! {
button {
// ✅ Because the `string` signal is `Copy`, we can copy it into the closure while still having access to it elsewhere
onclick: move |_| println!("{}", string),
"Print hello world"
}
button {
// ✅ Since `string` is `Copy`, we can move it into the onclick handler again
onclick: move |_| println!("{}", string),
"Print hello world again"
}
}
}- Calling
cloneon your data before you move it into the closure:
// `MyComponent` accepts a string which doesn't implement `Copy`
#[component]
fn MyComponent(string: String) -> Element {
rsx! {
button {
// ✅ The string only has one owner. We could move it into this closure, but since we want to use the string in other closures later, we will clone it instead
onclick: {
// Clone the string in a new block
let string = string.clone();
// Then move the cloned string into the closure
move |_| println!("{}", string)
},
"Print hello world"
}
button {
// ✅ We don't use the string after this closure, so we can just move it into the closure directly
onclick: move |_| println!("{}", string),
"Print hello world again"
}
}
}Sourcefn oncompositionstart<__Marker>(
self,
event_handler: impl EventHandlerValue<CompositionData, __Marker>,
) -> <Self as AttributeBuilderTarget>::Output
fn oncompositionstart<__Marker>( self, event_handler: impl EventHandlerValue<CompositionData, __Marker>, ) -> <Self as AttributeBuilderTarget>::Output
oncompositionstart
General Event Handler Information
§Event Handlers
Event Handlers let you react to user input in your application. In Dioxus, event handlers accept a closure that is called when the event occurs:
use dioxus::prelude::*;
fn App() -> Element {
rsx! {
button {
// The `onclick` event accepts a closure with the signature `fn(Event)`
onclick: |event_data| println!("clicked! I got the event data: {event_data:?}"),
"Click me"
}
}
}§Event Lifetimes
Events take a closure with the 'static lifetime. This means that the closure can only access data that either exists for the entire lifetime of the application, or data that you move into the closure.
State in dioxus is copy which makes it very easy to move into 'static closures like event handlers:
let mut count = use_signal(|| 0);
rsx! {
button {
// Since we added the `move` keyword, the closure will move the `count` signal into the closure
onclick: move |_| {
// This will panic because the `count` signal is not in scope
count.set(count() + 1);
},
"Click me"
}
};If you need to access data that is not Copy, you may need to clone the data before you move it into the closure:
// String is not `Copy`
let string = "hello world".to_string();
rsx! {
button {
// The string only has one owner. We could move it into this closure, but since we want to use the string in other closures later, we will clone it instead
onclick: {
// Clone the string in a new block
let string = string.clone();
// Then move the cloned string into the closure
move |_| println!("{}", string)
},
"Print hello world"
}
button {
// We don't use the string after this closure, so we can just move it into the closure directly
onclick: move |_| println!("{}", string),
"Print hello world again"
}
};§Async Event Handlers
In addition to closures that return nothing, you can also use async closures to handle events. If you return an async block from an event handler, dioxus will automatically spawn it:
use dioxus::prelude::*;
fn App() -> Element {
rsx! {
button {
// The `onclick` event can also accept a closure that returns an async block
onclick: move |_| async move {
tokio::time::sleep(std::time::Duration::from_secs(1)).await;
println!("You clicked the button one second ago!");
},
"Click me"
}
}
}§Compiler errors you may run into while using event handlers
function requires argument type to outlive `'static`
Event handler in Dioxus need only access data that can last for the entire lifetime of the application. That generally means data that is moved into the closure. If you get this error, you may have forgotten to add move to your closure.
Broken component:
// We return an Element which can last as long as the component is on the screen
fn App() -> Element {
// Signals are `Copy` which makes them very easy to move into `'static` closures like event handlers
let state = use_signal(|| "hello world".to_string());
rsx! {
button {
// ❌ Without `move`, rust will try to borrow the `state` signal which fails because the state signal is dropped at the end of the function
onclick: |_| {
println!("You clicked the button! The state is: {state}");
},
"Click me"
}
}
// The state signal is dropped here, but the event handler still needs to access it
}Fixed component:
fn App() -> Element {
let state = use_signal(|| "hello world".to_string());
rsx! {
button {
// ✅ The `move` keyword tells rust it can move the `state` signal into the closure. Since the closure owns the signal state, it can read it even after the function returns
onclick: move |_| {
println!("You clicked the button! The state is: {state}");
},
"Click me"
}
}
}use of moved value: `your_value` value used here after move
Data in rust has a single owner. If you run into this error, you have likely tried to move data that isn’t Copy into two different closures. You can fix this issue by making your data Copy or calling clone on it before you move it into the closure.
Broken component:
// `MyComponent` accepts a string which cannot be copied implicitly
#[component]
fn MyComponent(string: String) -> Element {
rsx! {
button {
// ❌ We are moving the string into the onclick handler which means we can't access it elsewhere
onclick: move |_| {
println!("{string}");
},
"Print hello world"
}
button {
// ❌ Since we already moved the string, we can't move it into the onclick handler again. This will cause a compiler error
onclick: move |_| {
println!("{string}");
},
"Print hello world again"
}
}
}You can fix this issue by either:
- Making your data
CopywithReadSignal:
// `MyComponent` accepts `ReadSignal<String>` which implements `Copy`
#[component]
fn MyComponent(string: ReadSignal<String>) -> Element {
rsx! {
button {
// ✅ Because the `string` signal is `Copy`, we can copy it into the closure while still having access to it elsewhere
onclick: move |_| println!("{}", string),
"Print hello world"
}
button {
// ✅ Since `string` is `Copy`, we can move it into the onclick handler again
onclick: move |_| println!("{}", string),
"Print hello world again"
}
}
}- Calling
cloneon your data before you move it into the closure:
// `MyComponent` accepts a string which doesn't implement `Copy`
#[component]
fn MyComponent(string: String) -> Element {
rsx! {
button {
// ✅ The string only has one owner. We could move it into this closure, but since we want to use the string in other closures later, we will clone it instead
onclick: {
// Clone the string in a new block
let string = string.clone();
// Then move the cloned string into the closure
move |_| println!("{}", string)
},
"Print hello world"
}
button {
// ✅ We don't use the string after this closure, so we can just move it into the closure directly
onclick: move |_| println!("{}", string),
"Print hello world again"
}
}
}Sourcefn oncompositionend<__Marker>(
self,
event_handler: impl EventHandlerValue<CompositionData, __Marker>,
) -> <Self as AttributeBuilderTarget>::Output
fn oncompositionend<__Marker>( self, event_handler: impl EventHandlerValue<CompositionData, __Marker>, ) -> <Self as AttributeBuilderTarget>::Output
oncompositionend
General Event Handler Information
§Event Handlers
Event Handlers let you react to user input in your application. In Dioxus, event handlers accept a closure that is called when the event occurs:
use dioxus::prelude::*;
fn App() -> Element {
rsx! {
button {
// The `onclick` event accepts a closure with the signature `fn(Event)`
onclick: |event_data| println!("clicked! I got the event data: {event_data:?}"),
"Click me"
}
}
}§Event Lifetimes
Events take a closure with the 'static lifetime. This means that the closure can only access data that either exists for the entire lifetime of the application, or data that you move into the closure.
State in dioxus is copy which makes it very easy to move into 'static closures like event handlers:
let mut count = use_signal(|| 0);
rsx! {
button {
// Since we added the `move` keyword, the closure will move the `count` signal into the closure
onclick: move |_| {
// This will panic because the `count` signal is not in scope
count.set(count() + 1);
},
"Click me"
}
};If you need to access data that is not Copy, you may need to clone the data before you move it into the closure:
// String is not `Copy`
let string = "hello world".to_string();
rsx! {
button {
// The string only has one owner. We could move it into this closure, but since we want to use the string in other closures later, we will clone it instead
onclick: {
// Clone the string in a new block
let string = string.clone();
// Then move the cloned string into the closure
move |_| println!("{}", string)
},
"Print hello world"
}
button {
// We don't use the string after this closure, so we can just move it into the closure directly
onclick: move |_| println!("{}", string),
"Print hello world again"
}
};§Async Event Handlers
In addition to closures that return nothing, you can also use async closures to handle events. If you return an async block from an event handler, dioxus will automatically spawn it:
use dioxus::prelude::*;
fn App() -> Element {
rsx! {
button {
// The `onclick` event can also accept a closure that returns an async block
onclick: move |_| async move {
tokio::time::sleep(std::time::Duration::from_secs(1)).await;
println!("You clicked the button one second ago!");
},
"Click me"
}
}
}§Compiler errors you may run into while using event handlers
function requires argument type to outlive `'static`
Event handler in Dioxus need only access data that can last for the entire lifetime of the application. That generally means data that is moved into the closure. If you get this error, you may have forgotten to add move to your closure.
Broken component:
// We return an Element which can last as long as the component is on the screen
fn App() -> Element {
// Signals are `Copy` which makes them very easy to move into `'static` closures like event handlers
let state = use_signal(|| "hello world".to_string());
rsx! {
button {
// ❌ Without `move`, rust will try to borrow the `state` signal which fails because the state signal is dropped at the end of the function
onclick: |_| {
println!("You clicked the button! The state is: {state}");
},
"Click me"
}
}
// The state signal is dropped here, but the event handler still needs to access it
}Fixed component:
fn App() -> Element {
let state = use_signal(|| "hello world".to_string());
rsx! {
button {
// ✅ The `move` keyword tells rust it can move the `state` signal into the closure. Since the closure owns the signal state, it can read it even after the function returns
onclick: move |_| {
println!("You clicked the button! The state is: {state}");
},
"Click me"
}
}
}use of moved value: `your_value` value used here after move
Data in rust has a single owner. If you run into this error, you have likely tried to move data that isn’t Copy into two different closures. You can fix this issue by making your data Copy or calling clone on it before you move it into the closure.
Broken component:
// `MyComponent` accepts a string which cannot be copied implicitly
#[component]
fn MyComponent(string: String) -> Element {
rsx! {
button {
// ❌ We are moving the string into the onclick handler which means we can't access it elsewhere
onclick: move |_| {
println!("{string}");
},
"Print hello world"
}
button {
// ❌ Since we already moved the string, we can't move it into the onclick handler again. This will cause a compiler error
onclick: move |_| {
println!("{string}");
},
"Print hello world again"
}
}
}You can fix this issue by either:
- Making your data
CopywithReadSignal:
// `MyComponent` accepts `ReadSignal<String>` which implements `Copy`
#[component]
fn MyComponent(string: ReadSignal<String>) -> Element {
rsx! {
button {
// ✅ Because the `string` signal is `Copy`, we can copy it into the closure while still having access to it elsewhere
onclick: move |_| println!("{}", string),
"Print hello world"
}
button {
// ✅ Since `string` is `Copy`, we can move it into the onclick handler again
onclick: move |_| println!("{}", string),
"Print hello world again"
}
}
}- Calling
cloneon your data before you move it into the closure:
// `MyComponent` accepts a string which doesn't implement `Copy`
#[component]
fn MyComponent(string: String) -> Element {
rsx! {
button {
// ✅ The string only has one owner. We could move it into this closure, but since we want to use the string in other closures later, we will clone it instead
onclick: {
// Clone the string in a new block
let string = string.clone();
// Then move the cloned string into the closure
move |_| println!("{}", string)
},
"Print hello world"
}
button {
// ✅ We don't use the string after this closure, so we can just move it into the closure directly
onclick: move |_| println!("{}", string),
"Print hello world again"
}
}
}Sourcefn oncompositionupdate<__Marker>(
self,
event_handler: impl EventHandlerValue<CompositionData, __Marker>,
) -> <Self as AttributeBuilderTarget>::Output
fn oncompositionupdate<__Marker>( self, event_handler: impl EventHandlerValue<CompositionData, __Marker>, ) -> <Self as AttributeBuilderTarget>::Output
oncompositionupdate
General Event Handler Information
§Event Handlers
Event Handlers let you react to user input in your application. In Dioxus, event handlers accept a closure that is called when the event occurs:
use dioxus::prelude::*;
fn App() -> Element {
rsx! {
button {
// The `onclick` event accepts a closure with the signature `fn(Event)`
onclick: |event_data| println!("clicked! I got the event data: {event_data:?}"),
"Click me"
}
}
}§Event Lifetimes
Events take a closure with the 'static lifetime. This means that the closure can only access data that either exists for the entire lifetime of the application, or data that you move into the closure.
State in dioxus is copy which makes it very easy to move into 'static closures like event handlers:
let mut count = use_signal(|| 0);
rsx! {
button {
// Since we added the `move` keyword, the closure will move the `count` signal into the closure
onclick: move |_| {
// This will panic because the `count` signal is not in scope
count.set(count() + 1);
},
"Click me"
}
};If you need to access data that is not Copy, you may need to clone the data before you move it into the closure:
// String is not `Copy`
let string = "hello world".to_string();
rsx! {
button {
// The string only has one owner. We could move it into this closure, but since we want to use the string in other closures later, we will clone it instead
onclick: {
// Clone the string in a new block
let string = string.clone();
// Then move the cloned string into the closure
move |_| println!("{}", string)
},
"Print hello world"
}
button {
// We don't use the string after this closure, so we can just move it into the closure directly
onclick: move |_| println!("{}", string),
"Print hello world again"
}
};§Async Event Handlers
In addition to closures that return nothing, you can also use async closures to handle events. If you return an async block from an event handler, dioxus will automatically spawn it:
use dioxus::prelude::*;
fn App() -> Element {
rsx! {
button {
// The `onclick` event can also accept a closure that returns an async block
onclick: move |_| async move {
tokio::time::sleep(std::time::Duration::from_secs(1)).await;
println!("You clicked the button one second ago!");
},
"Click me"
}
}
}§Compiler errors you may run into while using event handlers
function requires argument type to outlive `'static`
Event handler in Dioxus need only access data that can last for the entire lifetime of the application. That generally means data that is moved into the closure. If you get this error, you may have forgotten to add move to your closure.
Broken component:
// We return an Element which can last as long as the component is on the screen
fn App() -> Element {
// Signals are `Copy` which makes them very easy to move into `'static` closures like event handlers
let state = use_signal(|| "hello world".to_string());
rsx! {
button {
// ❌ Without `move`, rust will try to borrow the `state` signal which fails because the state signal is dropped at the end of the function
onclick: |_| {
println!("You clicked the button! The state is: {state}");
},
"Click me"
}
}
// The state signal is dropped here, but the event handler still needs to access it
}Fixed component:
fn App() -> Element {
let state = use_signal(|| "hello world".to_string());
rsx! {
button {
// ✅ The `move` keyword tells rust it can move the `state` signal into the closure. Since the closure owns the signal state, it can read it even after the function returns
onclick: move |_| {
println!("You clicked the button! The state is: {state}");
},
"Click me"
}
}
}use of moved value: `your_value` value used here after move
Data in rust has a single owner. If you run into this error, you have likely tried to move data that isn’t Copy into two different closures. You can fix this issue by making your data Copy or calling clone on it before you move it into the closure.
Broken component:
// `MyComponent` accepts a string which cannot be copied implicitly
#[component]
fn MyComponent(string: String) -> Element {
rsx! {
button {
// ❌ We are moving the string into the onclick handler which means we can't access it elsewhere
onclick: move |_| {
println!("{string}");
},
"Print hello world"
}
button {
// ❌ Since we already moved the string, we can't move it into the onclick handler again. This will cause a compiler error
onclick: move |_| {
println!("{string}");
},
"Print hello world again"
}
}
}You can fix this issue by either:
- Making your data
CopywithReadSignal:
// `MyComponent` accepts `ReadSignal<String>` which implements `Copy`
#[component]
fn MyComponent(string: ReadSignal<String>) -> Element {
rsx! {
button {
// ✅ Because the `string` signal is `Copy`, we can copy it into the closure while still having access to it elsewhere
onclick: move |_| println!("{}", string),
"Print hello world"
}
button {
// ✅ Since `string` is `Copy`, we can move it into the onclick handler again
onclick: move |_| println!("{}", string),
"Print hello world again"
}
}
}- Calling
cloneon your data before you move it into the closure:
// `MyComponent` accepts a string which doesn't implement `Copy`
#[component]
fn MyComponent(string: String) -> Element {
rsx! {
button {
// ✅ The string only has one owner. We could move it into this closure, but since we want to use the string in other closures later, we will clone it instead
onclick: {
// Clone the string in a new block
let string = string.clone();
// Then move the cloned string into the closure
move |_| println!("{}", string)
},
"Print hello world"
}
button {
// ✅ We don't use the string after this closure, so we can just move it into the closure directly
onclick: move |_| println!("{}", string),
"Print hello world again"
}
}
}Sourcefn ondrag<__Marker>(
self,
event_handler: impl EventHandlerValue<DragData, __Marker>,
) -> <Self as AttributeBuilderTarget>::Output
fn ondrag<__Marker>( self, event_handler: impl EventHandlerValue<DragData, __Marker>, ) -> <Self as AttributeBuilderTarget>::Output
ondrag
General Event Handler Information
§Event Handlers
Event Handlers let you react to user input in your application. In Dioxus, event handlers accept a closure that is called when the event occurs:
use dioxus::prelude::*;
fn App() -> Element {
rsx! {
button {
// The `onclick` event accepts a closure with the signature `fn(Event)`
onclick: |event_data| println!("clicked! I got the event data: {event_data:?}"),
"Click me"
}
}
}§Event Lifetimes
Events take a closure with the 'static lifetime. This means that the closure can only access data that either exists for the entire lifetime of the application, or data that you move into the closure.
State in dioxus is copy which makes it very easy to move into 'static closures like event handlers:
let mut count = use_signal(|| 0);
rsx! {
button {
// Since we added the `move` keyword, the closure will move the `count` signal into the closure
onclick: move |_| {
// This will panic because the `count` signal is not in scope
count.set(count() + 1);
},
"Click me"
}
};If you need to access data that is not Copy, you may need to clone the data before you move it into the closure:
// String is not `Copy`
let string = "hello world".to_string();
rsx! {
button {
// The string only has one owner. We could move it into this closure, but since we want to use the string in other closures later, we will clone it instead
onclick: {
// Clone the string in a new block
let string = string.clone();
// Then move the cloned string into the closure
move |_| println!("{}", string)
},
"Print hello world"
}
button {
// We don't use the string after this closure, so we can just move it into the closure directly
onclick: move |_| println!("{}", string),
"Print hello world again"
}
};§Async Event Handlers
In addition to closures that return nothing, you can also use async closures to handle events. If you return an async block from an event handler, dioxus will automatically spawn it:
use dioxus::prelude::*;
fn App() -> Element {
rsx! {
button {
// The `onclick` event can also accept a closure that returns an async block
onclick: move |_| async move {
tokio::time::sleep(std::time::Duration::from_secs(1)).await;
println!("You clicked the button one second ago!");
},
"Click me"
}
}
}§Compiler errors you may run into while using event handlers
function requires argument type to outlive `'static`
Event handler in Dioxus need only access data that can last for the entire lifetime of the application. That generally means data that is moved into the closure. If you get this error, you may have forgotten to add move to your closure.
Broken component:
// We return an Element which can last as long as the component is on the screen
fn App() -> Element {
// Signals are `Copy` which makes them very easy to move into `'static` closures like event handlers
let state = use_signal(|| "hello world".to_string());
rsx! {
button {
// ❌ Without `move`, rust will try to borrow the `state` signal which fails because the state signal is dropped at the end of the function
onclick: |_| {
println!("You clicked the button! The state is: {state}");
},
"Click me"
}
}
// The state signal is dropped here, but the event handler still needs to access it
}Fixed component:
fn App() -> Element {
let state = use_signal(|| "hello world".to_string());
rsx! {
button {
// ✅ The `move` keyword tells rust it can move the `state` signal into the closure. Since the closure owns the signal state, it can read it even after the function returns
onclick: move |_| {
println!("You clicked the button! The state is: {state}");
},
"Click me"
}
}
}use of moved value: `your_value` value used here after move
Data in rust has a single owner. If you run into this error, you have likely tried to move data that isn’t Copy into two different closures. You can fix this issue by making your data Copy or calling clone on it before you move it into the closure.
Broken component:
// `MyComponent` accepts a string which cannot be copied implicitly
#[component]
fn MyComponent(string: String) -> Element {
rsx! {
button {
// ❌ We are moving the string into the onclick handler which means we can't access it elsewhere
onclick: move |_| {
println!("{string}");
},
"Print hello world"
}
button {
// ❌ Since we already moved the string, we can't move it into the onclick handler again. This will cause a compiler error
onclick: move |_| {
println!("{string}");
},
"Print hello world again"
}
}
}You can fix this issue by either:
- Making your data
CopywithReadSignal:
// `MyComponent` accepts `ReadSignal<String>` which implements `Copy`
#[component]
fn MyComponent(string: ReadSignal<String>) -> Element {
rsx! {
button {
// ✅ Because the `string` signal is `Copy`, we can copy it into the closure while still having access to it elsewhere
onclick: move |_| println!("{}", string),
"Print hello world"
}
button {
// ✅ Since `string` is `Copy`, we can move it into the onclick handler again
onclick: move |_| println!("{}", string),
"Print hello world again"
}
}
}- Calling
cloneon your data before you move it into the closure:
// `MyComponent` accepts a string which doesn't implement `Copy`
#[component]
fn MyComponent(string: String) -> Element {
rsx! {
button {
// ✅ The string only has one owner. We could move it into this closure, but since we want to use the string in other closures later, we will clone it instead
onclick: {
// Clone the string in a new block
let string = string.clone();
// Then move the cloned string into the closure
move |_| println!("{}", string)
},
"Print hello world"
}
button {
// ✅ We don't use the string after this closure, so we can just move it into the closure directly
onclick: move |_| println!("{}", string),
"Print hello world again"
}
}
}Sourcefn ondragend<__Marker>(
self,
event_handler: impl EventHandlerValue<DragData, __Marker>,
) -> <Self as AttributeBuilderTarget>::Output
fn ondragend<__Marker>( self, event_handler: impl EventHandlerValue<DragData, __Marker>, ) -> <Self as AttributeBuilderTarget>::Output
ondragend
General Event Handler Information
§Event Handlers
Event Handlers let you react to user input in your application. In Dioxus, event handlers accept a closure that is called when the event occurs:
use dioxus::prelude::*;
fn App() -> Element {
rsx! {
button {
// The `onclick` event accepts a closure with the signature `fn(Event)`
onclick: |event_data| println!("clicked! I got the event data: {event_data:?}"),
"Click me"
}
}
}§Event Lifetimes
Events take a closure with the 'static lifetime. This means that the closure can only access data that either exists for the entire lifetime of the application, or data that you move into the closure.
State in dioxus is copy which makes it very easy to move into 'static closures like event handlers:
let mut count = use_signal(|| 0);
rsx! {
button {
// Since we added the `move` keyword, the closure will move the `count` signal into the closure
onclick: move |_| {
// This will panic because the `count` signal is not in scope
count.set(count() + 1);
},
"Click me"
}
};If you need to access data that is not Copy, you may need to clone the data before you move it into the closure:
// String is not `Copy`
let string = "hello world".to_string();
rsx! {
button {
// The string only has one owner. We could move it into this closure, but since we want to use the string in other closures later, we will clone it instead
onclick: {
// Clone the string in a new block
let string = string.clone();
// Then move the cloned string into the closure
move |_| println!("{}", string)
},
"Print hello world"
}
button {
// We don't use the string after this closure, so we can just move it into the closure directly
onclick: move |_| println!("{}", string),
"Print hello world again"
}
};§Async Event Handlers
In addition to closures that return nothing, you can also use async closures to handle events. If you return an async block from an event handler, dioxus will automatically spawn it:
use dioxus::prelude::*;
fn App() -> Element {
rsx! {
button {
// The `onclick` event can also accept a closure that returns an async block
onclick: move |_| async move {
tokio::time::sleep(std::time::Duration::from_secs(1)).await;
println!("You clicked the button one second ago!");
},
"Click me"
}
}
}§Compiler errors you may run into while using event handlers
function requires argument type to outlive `'static`
Event handler in Dioxus need only access data that can last for the entire lifetime of the application. That generally means data that is moved into the closure. If you get this error, you may have forgotten to add move to your closure.
Broken component:
// We return an Element which can last as long as the component is on the screen
fn App() -> Element {
// Signals are `Copy` which makes them very easy to move into `'static` closures like event handlers
let state = use_signal(|| "hello world".to_string());
rsx! {
button {
// ❌ Without `move`, rust will try to borrow the `state` signal which fails because the state signal is dropped at the end of the function
onclick: |_| {
println!("You clicked the button! The state is: {state}");
},
"Click me"
}
}
// The state signal is dropped here, but the event handler still needs to access it
}Fixed component:
fn App() -> Element {
let state = use_signal(|| "hello world".to_string());
rsx! {
button {
// ✅ The `move` keyword tells rust it can move the `state` signal into the closure. Since the closure owns the signal state, it can read it even after the function returns
onclick: move |_| {
println!("You clicked the button! The state is: {state}");
},
"Click me"
}
}
}use of moved value: `your_value` value used here after move
Data in rust has a single owner. If you run into this error, you have likely tried to move data that isn’t Copy into two different closures. You can fix this issue by making your data Copy or calling clone on it before you move it into the closure.
Broken component:
// `MyComponent` accepts a string which cannot be copied implicitly
#[component]
fn MyComponent(string: String) -> Element {
rsx! {
button {
// ❌ We are moving the string into the onclick handler which means we can't access it elsewhere
onclick: move |_| {
println!("{string}");
},
"Print hello world"
}
button {
// ❌ Since we already moved the string, we can't move it into the onclick handler again. This will cause a compiler error
onclick: move |_| {
println!("{string}");
},
"Print hello world again"
}
}
}You can fix this issue by either:
- Making your data
CopywithReadSignal:
// `MyComponent` accepts `ReadSignal<String>` which implements `Copy`
#[component]
fn MyComponent(string: ReadSignal<String>) -> Element {
rsx! {
button {
// ✅ Because the `string` signal is `Copy`, we can copy it into the closure while still having access to it elsewhere
onclick: move |_| println!("{}", string),
"Print hello world"
}
button {
// ✅ Since `string` is `Copy`, we can move it into the onclick handler again
onclick: move |_| println!("{}", string),
"Print hello world again"
}
}
}- Calling
cloneon your data before you move it into the closure:
// `MyComponent` accepts a string which doesn't implement `Copy`
#[component]
fn MyComponent(string: String) -> Element {
rsx! {
button {
// ✅ The string only has one owner. We could move it into this closure, but since we want to use the string in other closures later, we will clone it instead
onclick: {
// Clone the string in a new block
let string = string.clone();
// Then move the cloned string into the closure
move |_| println!("{}", string)
},
"Print hello world"
}
button {
// ✅ We don't use the string after this closure, so we can just move it into the closure directly
onclick: move |_| println!("{}", string),
"Print hello world again"
}
}
}Sourcefn ondragenter<__Marker>(
self,
event_handler: impl EventHandlerValue<DragData, __Marker>,
) -> <Self as AttributeBuilderTarget>::Output
fn ondragenter<__Marker>( self, event_handler: impl EventHandlerValue<DragData, __Marker>, ) -> <Self as AttributeBuilderTarget>::Output
ondragenter
General Event Handler Information
§Event Handlers
Event Handlers let you react to user input in your application. In Dioxus, event handlers accept a closure that is called when the event occurs:
use dioxus::prelude::*;
fn App() -> Element {
rsx! {
button {
// The `onclick` event accepts a closure with the signature `fn(Event)`
onclick: |event_data| println!("clicked! I got the event data: {event_data:?}"),
"Click me"
}
}
}§Event Lifetimes
Events take a closure with the 'static lifetime. This means that the closure can only access data that either exists for the entire lifetime of the application, or data that you move into the closure.
State in dioxus is copy which makes it very easy to move into 'static closures like event handlers:
let mut count = use_signal(|| 0);
rsx! {
button {
// Since we added the `move` keyword, the closure will move the `count` signal into the closure
onclick: move |_| {
// This will panic because the `count` signal is not in scope
count.set(count() + 1);
},
"Click me"
}
};If you need to access data that is not Copy, you may need to clone the data before you move it into the closure:
// String is not `Copy`
let string = "hello world".to_string();
rsx! {
button {
// The string only has one owner. We could move it into this closure, but since we want to use the string in other closures later, we will clone it instead
onclick: {
// Clone the string in a new block
let string = string.clone();
// Then move the cloned string into the closure
move |_| println!("{}", string)
},
"Print hello world"
}
button {
// We don't use the string after this closure, so we can just move it into the closure directly
onclick: move |_| println!("{}", string),
"Print hello world again"
}
};§Async Event Handlers
In addition to closures that return nothing, you can also use async closures to handle events. If you return an async block from an event handler, dioxus will automatically spawn it:
use dioxus::prelude::*;
fn App() -> Element {
rsx! {
button {
// The `onclick` event can also accept a closure that returns an async block
onclick: move |_| async move {
tokio::time::sleep(std::time::Duration::from_secs(1)).await;
println!("You clicked the button one second ago!");
},
"Click me"
}
}
}§Compiler errors you may run into while using event handlers
function requires argument type to outlive `'static`
Event handler in Dioxus need only access data that can last for the entire lifetime of the application. That generally means data that is moved into the closure. If you get this error, you may have forgotten to add move to your closure.
Broken component:
// We return an Element which can last as long as the component is on the screen
fn App() -> Element {
// Signals are `Copy` which makes them very easy to move into `'static` closures like event handlers
let state = use_signal(|| "hello world".to_string());
rsx! {
button {
// ❌ Without `move`, rust will try to borrow the `state` signal which fails because the state signal is dropped at the end of the function
onclick: |_| {
println!("You clicked the button! The state is: {state}");
},
"Click me"
}
}
// The state signal is dropped here, but the event handler still needs to access it
}Fixed component:
fn App() -> Element {
let state = use_signal(|| "hello world".to_string());
rsx! {
button {
// ✅ The `move` keyword tells rust it can move the `state` signal into the closure. Since the closure owns the signal state, it can read it even after the function returns
onclick: move |_| {
println!("You clicked the button! The state is: {state}");
},
"Click me"
}
}
}use of moved value: `your_value` value used here after move
Data in rust has a single owner. If you run into this error, you have likely tried to move data that isn’t Copy into two different closures. You can fix this issue by making your data Copy or calling clone on it before you move it into the closure.
Broken component:
// `MyComponent` accepts a string which cannot be copied implicitly
#[component]
fn MyComponent(string: String) -> Element {
rsx! {
button {
// ❌ We are moving the string into the onclick handler which means we can't access it elsewhere
onclick: move |_| {
println!("{string}");
},
"Print hello world"
}
button {
// ❌ Since we already moved the string, we can't move it into the onclick handler again. This will cause a compiler error
onclick: move |_| {
println!("{string}");
},
"Print hello world again"
}
}
}You can fix this issue by either:
- Making your data
CopywithReadSignal:
// `MyComponent` accepts `ReadSignal<String>` which implements `Copy`
#[component]
fn MyComponent(string: ReadSignal<String>) -> Element {
rsx! {
button {
// ✅ Because the `string` signal is `Copy`, we can copy it into the closure while still having access to it elsewhere
onclick: move |_| println!("{}", string),
"Print hello world"
}
button {
// ✅ Since `string` is `Copy`, we can move it into the onclick handler again
onclick: move |_| println!("{}", string),
"Print hello world again"
}
}
}- Calling
cloneon your data before you move it into the closure:
// `MyComponent` accepts a string which doesn't implement `Copy`
#[component]
fn MyComponent(string: String) -> Element {
rsx! {
button {
// ✅ The string only has one owner. We could move it into this closure, but since we want to use the string in other closures later, we will clone it instead
onclick: {
// Clone the string in a new block
let string = string.clone();
// Then move the cloned string into the closure
move |_| println!("{}", string)
},
"Print hello world"
}
button {
// ✅ We don't use the string after this closure, so we can just move it into the closure directly
onclick: move |_| println!("{}", string),
"Print hello world again"
}
}
}Sourcefn ondragexit<__Marker>(
self,
event_handler: impl EventHandlerValue<DragData, __Marker>,
) -> <Self as AttributeBuilderTarget>::Output
fn ondragexit<__Marker>( self, event_handler: impl EventHandlerValue<DragData, __Marker>, ) -> <Self as AttributeBuilderTarget>::Output
ondragexit
General Event Handler Information
§Event Handlers
Event Handlers let you react to user input in your application. In Dioxus, event handlers accept a closure that is called when the event occurs:
use dioxus::prelude::*;
fn App() -> Element {
rsx! {
button {
// The `onclick` event accepts a closure with the signature `fn(Event)`
onclick: |event_data| println!("clicked! I got the event data: {event_data:?}"),
"Click me"
}
}
}§Event Lifetimes
Events take a closure with the 'static lifetime. This means that the closure can only access data that either exists for the entire lifetime of the application, or data that you move into the closure.
State in dioxus is copy which makes it very easy to move into 'static closures like event handlers:
let mut count = use_signal(|| 0);
rsx! {
button {
// Since we added the `move` keyword, the closure will move the `count` signal into the closure
onclick: move |_| {
// This will panic because the `count` signal is not in scope
count.set(count() + 1);
},
"Click me"
}
};If you need to access data that is not Copy, you may need to clone the data before you move it into the closure:
// String is not `Copy`
let string = "hello world".to_string();
rsx! {
button {
// The string only has one owner. We could move it into this closure, but since we want to use the string in other closures later, we will clone it instead
onclick: {
// Clone the string in a new block
let string = string.clone();
// Then move the cloned string into the closure
move |_| println!("{}", string)
},
"Print hello world"
}
button {
// We don't use the string after this closure, so we can just move it into the closure directly
onclick: move |_| println!("{}", string),
"Print hello world again"
}
};§Async Event Handlers
In addition to closures that return nothing, you can also use async closures to handle events. If you return an async block from an event handler, dioxus will automatically spawn it:
use dioxus::prelude::*;
fn App() -> Element {
rsx! {
button {
// The `onclick` event can also accept a closure that returns an async block
onclick: move |_| async move {
tokio::time::sleep(std::time::Duration::from_secs(1)).await;
println!("You clicked the button one second ago!");
},
"Click me"
}
}
}§Compiler errors you may run into while using event handlers
function requires argument type to outlive `'static`
Event handler in Dioxus need only access data that can last for the entire lifetime of the application. That generally means data that is moved into the closure. If you get this error, you may have forgotten to add move to your closure.
Broken component:
// We return an Element which can last as long as the component is on the screen
fn App() -> Element {
// Signals are `Copy` which makes them very easy to move into `'static` closures like event handlers
let state = use_signal(|| "hello world".to_string());
rsx! {
button {
// ❌ Without `move`, rust will try to borrow the `state` signal which fails because the state signal is dropped at the end of the function
onclick: |_| {
println!("You clicked the button! The state is: {state}");
},
"Click me"
}
}
// The state signal is dropped here, but the event handler still needs to access it
}Fixed component:
fn App() -> Element {
let state = use_signal(|| "hello world".to_string());
rsx! {
button {
// ✅ The `move` keyword tells rust it can move the `state` signal into the closure. Since the closure owns the signal state, it can read it even after the function returns
onclick: move |_| {
println!("You clicked the button! The state is: {state}");
},
"Click me"
}
}
}use of moved value: `your_value` value used here after move
Data in rust has a single owner. If you run into this error, you have likely tried to move data that isn’t Copy into two different closures. You can fix this issue by making your data Copy or calling clone on it before you move it into the closure.
Broken component:
// `MyComponent` accepts a string which cannot be copied implicitly
#[component]
fn MyComponent(string: String) -> Element {
rsx! {
button {
// ❌ We are moving the string into the onclick handler which means we can't access it elsewhere
onclick: move |_| {
println!("{string}");
},
"Print hello world"
}
button {
// ❌ Since we already moved the string, we can't move it into the onclick handler again. This will cause a compiler error
onclick: move |_| {
println!("{string}");
},
"Print hello world again"
}
}
}You can fix this issue by either:
- Making your data
CopywithReadSignal:
// `MyComponent` accepts `ReadSignal<String>` which implements `Copy`
#[component]
fn MyComponent(string: ReadSignal<String>) -> Element {
rsx! {
button {
// ✅ Because the `string` signal is `Copy`, we can copy it into the closure while still having access to it elsewhere
onclick: move |_| println!("{}", string),
"Print hello world"
}
button {
// ✅ Since `string` is `Copy`, we can move it into the onclick handler again
onclick: move |_| println!("{}", string),
"Print hello world again"
}
}
}- Calling
cloneon your data before you move it into the closure:
// `MyComponent` accepts a string which doesn't implement `Copy`
#[component]
fn MyComponent(string: String) -> Element {
rsx! {
button {
// ✅ The string only has one owner. We could move it into this closure, but since we want to use the string in other closures later, we will clone it instead
onclick: {
// Clone the string in a new block
let string = string.clone();
// Then move the cloned string into the closure
move |_| println!("{}", string)
},
"Print hello world"
}
button {
// ✅ We don't use the string after this closure, so we can just move it into the closure directly
onclick: move |_| println!("{}", string),
"Print hello world again"
}
}
}Sourcefn ondragleave<__Marker>(
self,
event_handler: impl EventHandlerValue<DragData, __Marker>,
) -> <Self as AttributeBuilderTarget>::Output
fn ondragleave<__Marker>( self, event_handler: impl EventHandlerValue<DragData, __Marker>, ) -> <Self as AttributeBuilderTarget>::Output
ondragleave
General Event Handler Information
§Event Handlers
Event Handlers let you react to user input in your application. In Dioxus, event handlers accept a closure that is called when the event occurs:
use dioxus::prelude::*;
fn App() -> Element {
rsx! {
button {
// The `onclick` event accepts a closure with the signature `fn(Event)`
onclick: |event_data| println!("clicked! I got the event data: {event_data:?}"),
"Click me"
}
}
}§Event Lifetimes
Events take a closure with the 'static lifetime. This means that the closure can only access data that either exists for the entire lifetime of the application, or data that you move into the closure.
State in dioxus is copy which makes it very easy to move into 'static closures like event handlers:
let mut count = use_signal(|| 0);
rsx! {
button {
// Since we added the `move` keyword, the closure will move the `count` signal into the closure
onclick: move |_| {
// This will panic because the `count` signal is not in scope
count.set(count() + 1);
},
"Click me"
}
};If you need to access data that is not Copy, you may need to clone the data before you move it into the closure:
// String is not `Copy`
let string = "hello world".to_string();
rsx! {
button {
// The string only has one owner. We could move it into this closure, but since we want to use the string in other closures later, we will clone it instead
onclick: {
// Clone the string in a new block
let string = string.clone();
// Then move the cloned string into the closure
move |_| println!("{}", string)
},
"Print hello world"
}
button {
// We don't use the string after this closure, so we can just move it into the closure directly
onclick: move |_| println!("{}", string),
"Print hello world again"
}
};§Async Event Handlers
In addition to closures that return nothing, you can also use async closures to handle events. If you return an async block from an event handler, dioxus will automatically spawn it:
use dioxus::prelude::*;
fn App() -> Element {
rsx! {
button {
// The `onclick` event can also accept a closure that returns an async block
onclick: move |_| async move {
tokio::time::sleep(std::time::Duration::from_secs(1)).await;
println!("You clicked the button one second ago!");
},
"Click me"
}
}
}§Compiler errors you may run into while using event handlers
function requires argument type to outlive `'static`
Event handler in Dioxus need only access data that can last for the entire lifetime of the application. That generally means data that is moved into the closure. If you get this error, you may have forgotten to add move to your closure.
Broken component:
// We return an Element which can last as long as the component is on the screen
fn App() -> Element {
// Signals are `Copy` which makes them very easy to move into `'static` closures like event handlers
let state = use_signal(|| "hello world".to_string());
rsx! {
button {
// ❌ Without `move`, rust will try to borrow the `state` signal which fails because the state signal is dropped at the end of the function
onclick: |_| {
println!("You clicked the button! The state is: {state}");
},
"Click me"
}
}
// The state signal is dropped here, but the event handler still needs to access it
}Fixed component:
fn App() -> Element {
let state = use_signal(|| "hello world".to_string());
rsx! {
button {
// ✅ The `move` keyword tells rust it can move the `state` signal into the closure. Since the closure owns the signal state, it can read it even after the function returns
onclick: move |_| {
println!("You clicked the button! The state is: {state}");
},
"Click me"
}
}
}use of moved value: `your_value` value used here after move
Data in rust has a single owner. If you run into this error, you have likely tried to move data that isn’t Copy into two different closures. You can fix this issue by making your data Copy or calling clone on it before you move it into the closure.
Broken component:
// `MyComponent` accepts a string which cannot be copied implicitly
#[component]
fn MyComponent(string: String) -> Element {
rsx! {
button {
// ❌ We are moving the string into the onclick handler which means we can't access it elsewhere
onclick: move |_| {
println!("{string}");
},
"Print hello world"
}
button {
// ❌ Since we already moved the string, we can't move it into the onclick handler again. This will cause a compiler error
onclick: move |_| {
println!("{string}");
},
"Print hello world again"
}
}
}You can fix this issue by either:
- Making your data
CopywithReadSignal:
// `MyComponent` accepts `ReadSignal<String>` which implements `Copy`
#[component]
fn MyComponent(string: ReadSignal<String>) -> Element {
rsx! {
button {
// ✅ Because the `string` signal is `Copy`, we can copy it into the closure while still having access to it elsewhere
onclick: move |_| println!("{}", string),
"Print hello world"
}
button {
// ✅ Since `string` is `Copy`, we can move it into the onclick handler again
onclick: move |_| println!("{}", string),
"Print hello world again"
}
}
}- Calling
cloneon your data before you move it into the closure:
// `MyComponent` accepts a string which doesn't implement `Copy`
#[component]
fn MyComponent(string: String) -> Element {
rsx! {
button {
// ✅ The string only has one owner. We could move it into this closure, but since we want to use the string in other closures later, we will clone it instead
onclick: {
// Clone the string in a new block
let string = string.clone();
// Then move the cloned string into the closure
move |_| println!("{}", string)
},
"Print hello world"
}
button {
// ✅ We don't use the string after this closure, so we can just move it into the closure directly
onclick: move |_| println!("{}", string),
"Print hello world again"
}
}
}Sourcefn ondragover<__Marker>(
self,
event_handler: impl EventHandlerValue<DragData, __Marker>,
) -> <Self as AttributeBuilderTarget>::Output
fn ondragover<__Marker>( self, event_handler: impl EventHandlerValue<DragData, __Marker>, ) -> <Self as AttributeBuilderTarget>::Output
ondragover
General Event Handler Information
§Event Handlers
Event Handlers let you react to user input in your application. In Dioxus, event handlers accept a closure that is called when the event occurs:
use dioxus::prelude::*;
fn App() -> Element {
rsx! {
button {
// The `onclick` event accepts a closure with the signature `fn(Event)`
onclick: |event_data| println!("clicked! I got the event data: {event_data:?}"),
"Click me"
}
}
}§Event Lifetimes
Events take a closure with the 'static lifetime. This means that the closure can only access data that either exists for the entire lifetime of the application, or data that you move into the closure.
State in dioxus is copy which makes it very easy to move into 'static closures like event handlers:
let mut count = use_signal(|| 0);
rsx! {
button {
// Since we added the `move` keyword, the closure will move the `count` signal into the closure
onclick: move |_| {
// This will panic because the `count` signal is not in scope
count.set(count() + 1);
},
"Click me"
}
};If you need to access data that is not Copy, you may need to clone the data before you move it into the closure:
// String is not `Copy`
let string = "hello world".to_string();
rsx! {
button {
// The string only has one owner. We could move it into this closure, but since we want to use the string in other closures later, we will clone it instead
onclick: {
// Clone the string in a new block
let string = string.clone();
// Then move the cloned string into the closure
move |_| println!("{}", string)
},
"Print hello world"
}
button {
// We don't use the string after this closure, so we can just move it into the closure directly
onclick: move |_| println!("{}", string),
"Print hello world again"
}
};§Async Event Handlers
In addition to closures that return nothing, you can also use async closures to handle events. If you return an async block from an event handler, dioxus will automatically spawn it:
use dioxus::prelude::*;
fn App() -> Element {
rsx! {
button {
// The `onclick` event can also accept a closure that returns an async block
onclick: move |_| async move {
tokio::time::sleep(std::time::Duration::from_secs(1)).await;
println!("You clicked the button one second ago!");
},
"Click me"
}
}
}§Compiler errors you may run into while using event handlers
function requires argument type to outlive `'static`
Event handler in Dioxus need only access data that can last for the entire lifetime of the application. That generally means data that is moved into the closure. If you get this error, you may have forgotten to add move to your closure.
Broken component:
// We return an Element which can last as long as the component is on the screen
fn App() -> Element {
// Signals are `Copy` which makes them very easy to move into `'static` closures like event handlers
let state = use_signal(|| "hello world".to_string());
rsx! {
button {
// ❌ Without `move`, rust will try to borrow the `state` signal which fails because the state signal is dropped at the end of the function
onclick: |_| {
println!("You clicked the button! The state is: {state}");
},
"Click me"
}
}
// The state signal is dropped here, but the event handler still needs to access it
}Fixed component:
fn App() -> Element {
let state = use_signal(|| "hello world".to_string());
rsx! {
button {
// ✅ The `move` keyword tells rust it can move the `state` signal into the closure. Since the closure owns the signal state, it can read it even after the function returns
onclick: move |_| {
println!("You clicked the button! The state is: {state}");
},
"Click me"
}
}
}use of moved value: `your_value` value used here after move
Data in rust has a single owner. If you run into this error, you have likely tried to move data that isn’t Copy into two different closures. You can fix this issue by making your data Copy or calling clone on it before you move it into the closure.
Broken component:
// `MyComponent` accepts a string which cannot be copied implicitly
#[component]
fn MyComponent(string: String) -> Element {
rsx! {
button {
// ❌ We are moving the string into the onclick handler which means we can't access it elsewhere
onclick: move |_| {
println!("{string}");
},
"Print hello world"
}
button {
// ❌ Since we already moved the string, we can't move it into the onclick handler again. This will cause a compiler error
onclick: move |_| {
println!("{string}");
},
"Print hello world again"
}
}
}You can fix this issue by either:
- Making your data
CopywithReadSignal:
// `MyComponent` accepts `ReadSignal<String>` which implements `Copy`
#[component]
fn MyComponent(string: ReadSignal<String>) -> Element {
rsx! {
button {
// ✅ Because the `string` signal is `Copy`, we can copy it into the closure while still having access to it elsewhere
onclick: move |_| println!("{}", string),
"Print hello world"
}
button {
// ✅ Since `string` is `Copy`, we can move it into the onclick handler again
onclick: move |_| println!("{}", string),
"Print hello world again"
}
}
}- Calling
cloneon your data before you move it into the closure:
// `MyComponent` accepts a string which doesn't implement `Copy`
#[component]
fn MyComponent(string: String) -> Element {
rsx! {
button {
// ✅ The string only has one owner. We could move it into this closure, but since we want to use the string in other closures later, we will clone it instead
onclick: {
// Clone the string in a new block
let string = string.clone();
// Then move the cloned string into the closure
move |_| println!("{}", string)
},
"Print hello world"
}
button {
// ✅ We don't use the string after this closure, so we can just move it into the closure directly
onclick: move |_| println!("{}", string),
"Print hello world again"
}
}
}Sourcefn ondragstart<__Marker>(
self,
event_handler: impl EventHandlerValue<DragData, __Marker>,
) -> <Self as AttributeBuilderTarget>::Output
fn ondragstart<__Marker>( self, event_handler: impl EventHandlerValue<DragData, __Marker>, ) -> <Self as AttributeBuilderTarget>::Output
ondragstart
General Event Handler Information
§Event Handlers
Event Handlers let you react to user input in your application. In Dioxus, event handlers accept a closure that is called when the event occurs:
use dioxus::prelude::*;
fn App() -> Element {
rsx! {
button {
// The `onclick` event accepts a closure with the signature `fn(Event)`
onclick: |event_data| println!("clicked! I got the event data: {event_data:?}"),
"Click me"
}
}
}§Event Lifetimes
Events take a closure with the 'static lifetime. This means that the closure can only access data that either exists for the entire lifetime of the application, or data that you move into the closure.
State in dioxus is copy which makes it very easy to move into 'static closures like event handlers:
let mut count = use_signal(|| 0);
rsx! {
button {
// Since we added the `move` keyword, the closure will move the `count` signal into the closure
onclick: move |_| {
// This will panic because the `count` signal is not in scope
count.set(count() + 1);
},
"Click me"
}
};If you need to access data that is not Copy, you may need to clone the data before you move it into the closure:
// String is not `Copy`
let string = "hello world".to_string();
rsx! {
button {
// The string only has one owner. We could move it into this closure, but since we want to use the string in other closures later, we will clone it instead
onclick: {
// Clone the string in a new block
let string = string.clone();
// Then move the cloned string into the closure
move |_| println!("{}", string)
},
"Print hello world"
}
button {
// We don't use the string after this closure, so we can just move it into the closure directly
onclick: move |_| println!("{}", string),
"Print hello world again"
}
};§Async Event Handlers
In addition to closures that return nothing, you can also use async closures to handle events. If you return an async block from an event handler, dioxus will automatically spawn it:
use dioxus::prelude::*;
fn App() -> Element {
rsx! {
button {
// The `onclick` event can also accept a closure that returns an async block
onclick: move |_| async move {
tokio::time::sleep(std::time::Duration::from_secs(1)).await;
println!("You clicked the button one second ago!");
},
"Click me"
}
}
}§Compiler errors you may run into while using event handlers
function requires argument type to outlive `'static`
Event handler in Dioxus need only access data that can last for the entire lifetime of the application. That generally means data that is moved into the closure. If you get this error, you may have forgotten to add move to your closure.
Broken component:
// We return an Element which can last as long as the component is on the screen
fn App() -> Element {
// Signals are `Copy` which makes them very easy to move into `'static` closures like event handlers
let state = use_signal(|| "hello world".to_string());
rsx! {
button {
// ❌ Without `move`, rust will try to borrow the `state` signal which fails because the state signal is dropped at the end of the function
onclick: |_| {
println!("You clicked the button! The state is: {state}");
},
"Click me"
}
}
// The state signal is dropped here, but the event handler still needs to access it
}Fixed component:
fn App() -> Element {
let state = use_signal(|| "hello world".to_string());
rsx! {
button {
// ✅ The `move` keyword tells rust it can move the `state` signal into the closure. Since the closure owns the signal state, it can read it even after the function returns
onclick: move |_| {
println!("You clicked the button! The state is: {state}");
},
"Click me"
}
}
}use of moved value: `your_value` value used here after move
Data in rust has a single owner. If you run into this error, you have likely tried to move data that isn’t Copy into two different closures. You can fix this issue by making your data Copy or calling clone on it before you move it into the closure.
Broken component:
// `MyComponent` accepts a string which cannot be copied implicitly
#[component]
fn MyComponent(string: String) -> Element {
rsx! {
button {
// ❌ We are moving the string into the onclick handler which means we can't access it elsewhere
onclick: move |_| {
println!("{string}");
},
"Print hello world"
}
button {
// ❌ Since we already moved the string, we can't move it into the onclick handler again. This will cause a compiler error
onclick: move |_| {
println!("{string}");
},
"Print hello world again"
}
}
}You can fix this issue by either:
- Making your data
CopywithReadSignal:
// `MyComponent` accepts `ReadSignal<String>` which implements `Copy`
#[component]
fn MyComponent(string: ReadSignal<String>) -> Element {
rsx! {
button {
// ✅ Because the `string` signal is `Copy`, we can copy it into the closure while still having access to it elsewhere
onclick: move |_| println!("{}", string),
"Print hello world"
}
button {
// ✅ Since `string` is `Copy`, we can move it into the onclick handler again
onclick: move |_| println!("{}", string),
"Print hello world again"
}
}
}- Calling
cloneon your data before you move it into the closure:
// `MyComponent` accepts a string which doesn't implement `Copy`
#[component]
fn MyComponent(string: String) -> Element {
rsx! {
button {
// ✅ The string only has one owner. We could move it into this closure, but since we want to use the string in other closures later, we will clone it instead
onclick: {
// Clone the string in a new block
let string = string.clone();
// Then move the cloned string into the closure
move |_| println!("{}", string)
},
"Print hello world"
}
button {
// ✅ We don't use the string after this closure, so we can just move it into the closure directly
onclick: move |_| println!("{}", string),
"Print hello world again"
}
}
}Sourcefn ondrop<__Marker>(
self,
event_handler: impl EventHandlerValue<DragData, __Marker>,
) -> <Self as AttributeBuilderTarget>::Output
fn ondrop<__Marker>( self, event_handler: impl EventHandlerValue<DragData, __Marker>, ) -> <Self as AttributeBuilderTarget>::Output
ondrop
General Event Handler Information
§Event Handlers
Event Handlers let you react to user input in your application. In Dioxus, event handlers accept a closure that is called when the event occurs:
use dioxus::prelude::*;
fn App() -> Element {
rsx! {
button {
// The `onclick` event accepts a closure with the signature `fn(Event)`
onclick: |event_data| println!("clicked! I got the event data: {event_data:?}"),
"Click me"
}
}
}§Event Lifetimes
Events take a closure with the 'static lifetime. This means that the closure can only access data that either exists for the entire lifetime of the application, or data that you move into the closure.
State in dioxus is copy which makes it very easy to move into 'static closures like event handlers:
let mut count = use_signal(|| 0);
rsx! {
button {
// Since we added the `move` keyword, the closure will move the `count` signal into the closure
onclick: move |_| {
// This will panic because the `count` signal is not in scope
count.set(count() + 1);
},
"Click me"
}
};If you need to access data that is not Copy, you may need to clone the data before you move it into the closure:
// String is not `Copy`
let string = "hello world".to_string();
rsx! {
button {
// The string only has one owner. We could move it into this closure, but since we want to use the string in other closures later, we will clone it instead
onclick: {
// Clone the string in a new block
let string = string.clone();
// Then move the cloned string into the closure
move |_| println!("{}", string)
},
"Print hello world"
}
button {
// We don't use the string after this closure, so we can just move it into the closure directly
onclick: move |_| println!("{}", string),
"Print hello world again"
}
};§Async Event Handlers
In addition to closures that return nothing, you can also use async closures to handle events. If you return an async block from an event handler, dioxus will automatically spawn it:
use dioxus::prelude::*;
fn App() -> Element {
rsx! {
button {
// The `onclick` event can also accept a closure that returns an async block
onclick: move |_| async move {
tokio::time::sleep(std::time::Duration::from_secs(1)).await;
println!("You clicked the button one second ago!");
},
"Click me"
}
}
}§Compiler errors you may run into while using event handlers
function requires argument type to outlive `'static`
Event handler in Dioxus need only access data that can last for the entire lifetime of the application. That generally means data that is moved into the closure. If you get this error, you may have forgotten to add move to your closure.
Broken component:
// We return an Element which can last as long as the component is on the screen
fn App() -> Element {
// Signals are `Copy` which makes them very easy to move into `'static` closures like event handlers
let state = use_signal(|| "hello world".to_string());
rsx! {
button {
// ❌ Without `move`, rust will try to borrow the `state` signal which fails because the state signal is dropped at the end of the function
onclick: |_| {
println!("You clicked the button! The state is: {state}");
},
"Click me"
}
}
// The state signal is dropped here, but the event handler still needs to access it
}Fixed component:
fn App() -> Element {
let state = use_signal(|| "hello world".to_string());
rsx! {
button {
// ✅ The `move` keyword tells rust it can move the `state` signal into the closure. Since the closure owns the signal state, it can read it even after the function returns
onclick: move |_| {
println!("You clicked the button! The state is: {state}");
},
"Click me"
}
}
}use of moved value: `your_value` value used here after move
Data in rust has a single owner. If you run into this error, you have likely tried to move data that isn’t Copy into two different closures. You can fix this issue by making your data Copy or calling clone on it before you move it into the closure.
Broken component:
// `MyComponent` accepts a string which cannot be copied implicitly
#[component]
fn MyComponent(string: String) -> Element {
rsx! {
button {
// ❌ We are moving the string into the onclick handler which means we can't access it elsewhere
onclick: move |_| {
println!("{string}");
},
"Print hello world"
}
button {
// ❌ Since we already moved the string, we can't move it into the onclick handler again. This will cause a compiler error
onclick: move |_| {
println!("{string}");
},
"Print hello world again"
}
}
}You can fix this issue by either:
- Making your data
CopywithReadSignal:
// `MyComponent` accepts `ReadSignal<String>` which implements `Copy`
#[component]
fn MyComponent(string: ReadSignal<String>) -> Element {
rsx! {
button {
// ✅ Because the `string` signal is `Copy`, we can copy it into the closure while still having access to it elsewhere
onclick: move |_| println!("{}", string),
"Print hello world"
}
button {
// ✅ Since `string` is `Copy`, we can move it into the onclick handler again
onclick: move |_| println!("{}", string),
"Print hello world again"
}
}
}- Calling
cloneon your data before you move it into the closure:
// `MyComponent` accepts a string which doesn't implement `Copy`
#[component]
fn MyComponent(string: String) -> Element {
rsx! {
button {
// ✅ The string only has one owner. We could move it into this closure, but since we want to use the string in other closures later, we will clone it instead
onclick: {
// Clone the string in a new block
let string = string.clone();
// Then move the cloned string into the closure
move |_| println!("{}", string)
},
"Print hello world"
}
button {
// ✅ We don't use the string after this closure, so we can just move it into the closure directly
onclick: move |_| println!("{}", string),
"Print hello world again"
}
}
}Sourcefn onfocus<__Marker>(
self,
event_handler: impl EventHandlerValue<FocusData, __Marker>,
) -> <Self as AttributeBuilderTarget>::Output
fn onfocus<__Marker>( self, event_handler: impl EventHandlerValue<FocusData, __Marker>, ) -> <Self as AttributeBuilderTarget>::Output
onfocus
General Event Handler Information
§Event Handlers
Event Handlers let you react to user input in your application. In Dioxus, event handlers accept a closure that is called when the event occurs:
use dioxus::prelude::*;
fn App() -> Element {
rsx! {
button {
// The `onclick` event accepts a closure with the signature `fn(Event)`
onclick: |event_data| println!("clicked! I got the event data: {event_data:?}"),
"Click me"
}
}
}§Event Lifetimes
Events take a closure with the 'static lifetime. This means that the closure can only access data that either exists for the entire lifetime of the application, or data that you move into the closure.
State in dioxus is copy which makes it very easy to move into 'static closures like event handlers:
let mut count = use_signal(|| 0);
rsx! {
button {
// Since we added the `move` keyword, the closure will move the `count` signal into the closure
onclick: move |_| {
// This will panic because the `count` signal is not in scope
count.set(count() + 1);
},
"Click me"
}
};If you need to access data that is not Copy, you may need to clone the data before you move it into the closure:
// String is not `Copy`
let string = "hello world".to_string();
rsx! {
button {
// The string only has one owner. We could move it into this closure, but since we want to use the string in other closures later, we will clone it instead
onclick: {
// Clone the string in a new block
let string = string.clone();
// Then move the cloned string into the closure
move |_| println!("{}", string)
},
"Print hello world"
}
button {
// We don't use the string after this closure, so we can just move it into the closure directly
onclick: move |_| println!("{}", string),
"Print hello world again"
}
};§Async Event Handlers
In addition to closures that return nothing, you can also use async closures to handle events. If you return an async block from an event handler, dioxus will automatically spawn it:
use dioxus::prelude::*;
fn App() -> Element {
rsx! {
button {
// The `onclick` event can also accept a closure that returns an async block
onclick: move |_| async move {
tokio::time::sleep(std::time::Duration::from_secs(1)).await;
println!("You clicked the button one second ago!");
},
"Click me"
}
}
}§Compiler errors you may run into while using event handlers
function requires argument type to outlive `'static`
Event handler in Dioxus need only access data that can last for the entire lifetime of the application. That generally means data that is moved into the closure. If you get this error, you may have forgotten to add move to your closure.
Broken component:
// We return an Element which can last as long as the component is on the screen
fn App() -> Element {
// Signals are `Copy` which makes them very easy to move into `'static` closures like event handlers
let state = use_signal(|| "hello world".to_string());
rsx! {
button {
// ❌ Without `move`, rust will try to borrow the `state` signal which fails because the state signal is dropped at the end of the function
onclick: |_| {
println!("You clicked the button! The state is: {state}");
},
"Click me"
}
}
// The state signal is dropped here, but the event handler still needs to access it
}Fixed component:
fn App() -> Element {
let state = use_signal(|| "hello world".to_string());
rsx! {
button {
// ✅ The `move` keyword tells rust it can move the `state` signal into the closure. Since the closure owns the signal state, it can read it even after the function returns
onclick: move |_| {
println!("You clicked the button! The state is: {state}");
},
"Click me"
}
}
}use of moved value: `your_value` value used here after move
Data in rust has a single owner. If you run into this error, you have likely tried to move data that isn’t Copy into two different closures. You can fix this issue by making your data Copy or calling clone on it before you move it into the closure.
Broken component:
// `MyComponent` accepts a string which cannot be copied implicitly
#[component]
fn MyComponent(string: String) -> Element {
rsx! {
button {
// ❌ We are moving the string into the onclick handler which means we can't access it elsewhere
onclick: move |_| {
println!("{string}");
},
"Print hello world"
}
button {
// ❌ Since we already moved the string, we can't move it into the onclick handler again. This will cause a compiler error
onclick: move |_| {
println!("{string}");
},
"Print hello world again"
}
}
}You can fix this issue by either:
- Making your data
CopywithReadSignal:
// `MyComponent` accepts `ReadSignal<String>` which implements `Copy`
#[component]
fn MyComponent(string: ReadSignal<String>) -> Element {
rsx! {
button {
// ✅ Because the `string` signal is `Copy`, we can copy it into the closure while still having access to it elsewhere
onclick: move |_| println!("{}", string),
"Print hello world"
}
button {
// ✅ Since `string` is `Copy`, we can move it into the onclick handler again
onclick: move |_| println!("{}", string),
"Print hello world again"
}
}
}- Calling
cloneon your data before you move it into the closure:
// `MyComponent` accepts a string which doesn't implement `Copy`
#[component]
fn MyComponent(string: String) -> Element {
rsx! {
button {
// ✅ The string only has one owner. We could move it into this closure, but since we want to use the string in other closures later, we will clone it instead
onclick: {
// Clone the string in a new block
let string = string.clone();
// Then move the cloned string into the closure
move |_| println!("{}", string)
},
"Print hello world"
}
button {
// ✅ We don't use the string after this closure, so we can just move it into the closure directly
onclick: move |_| println!("{}", string),
"Print hello world again"
}
}
}Sourcefn onfocusout<__Marker>(
self,
event_handler: impl EventHandlerValue<FocusData, __Marker>,
) -> <Self as AttributeBuilderTarget>::Output
fn onfocusout<__Marker>( self, event_handler: impl EventHandlerValue<FocusData, __Marker>, ) -> <Self as AttributeBuilderTarget>::Output
onfocusout
General Event Handler Information
§Event Handlers
Event Handlers let you react to user input in your application. In Dioxus, event handlers accept a closure that is called when the event occurs:
use dioxus::prelude::*;
fn App() -> Element {
rsx! {
button {
// The `onclick` event accepts a closure with the signature `fn(Event)`
onclick: |event_data| println!("clicked! I got the event data: {event_data:?}"),
"Click me"
}
}
}§Event Lifetimes
Events take a closure with the 'static lifetime. This means that the closure can only access data that either exists for the entire lifetime of the application, or data that you move into the closure.
State in dioxus is copy which makes it very easy to move into 'static closures like event handlers:
let mut count = use_signal(|| 0);
rsx! {
button {
// Since we added the `move` keyword, the closure will move the `count` signal into the closure
onclick: move |_| {
// This will panic because the `count` signal is not in scope
count.set(count() + 1);
},
"Click me"
}
};If you need to access data that is not Copy, you may need to clone the data before you move it into the closure:
// String is not `Copy`
let string = "hello world".to_string();
rsx! {
button {
// The string only has one owner. We could move it into this closure, but since we want to use the string in other closures later, we will clone it instead
onclick: {
// Clone the string in a new block
let string = string.clone();
// Then move the cloned string into the closure
move |_| println!("{}", string)
},
"Print hello world"
}
button {
// We don't use the string after this closure, so we can just move it into the closure directly
onclick: move |_| println!("{}", string),
"Print hello world again"
}
};§Async Event Handlers
In addition to closures that return nothing, you can also use async closures to handle events. If you return an async block from an event handler, dioxus will automatically spawn it:
use dioxus::prelude::*;
fn App() -> Element {
rsx! {
button {
// The `onclick` event can also accept a closure that returns an async block
onclick: move |_| async move {
tokio::time::sleep(std::time::Duration::from_secs(1)).await;
println!("You clicked the button one second ago!");
},
"Click me"
}
}
}§Compiler errors you may run into while using event handlers
function requires argument type to outlive `'static`
Event handler in Dioxus need only access data that can last for the entire lifetime of the application. That generally means data that is moved into the closure. If you get this error, you may have forgotten to add move to your closure.
Broken component:
// We return an Element which can last as long as the component is on the screen
fn App() -> Element {
// Signals are `Copy` which makes them very easy to move into `'static` closures like event handlers
let state = use_signal(|| "hello world".to_string());
rsx! {
button {
// ❌ Without `move`, rust will try to borrow the `state` signal which fails because the state signal is dropped at the end of the function
onclick: |_| {
println!("You clicked the button! The state is: {state}");
},
"Click me"
}
}
// The state signal is dropped here, but the event handler still needs to access it
}Fixed component:
fn App() -> Element {
let state = use_signal(|| "hello world".to_string());
rsx! {
button {
// ✅ The `move` keyword tells rust it can move the `state` signal into the closure. Since the closure owns the signal state, it can read it even after the function returns
onclick: move |_| {
println!("You clicked the button! The state is: {state}");
},
"Click me"
}
}
}use of moved value: `your_value` value used here after move
Data in rust has a single owner. If you run into this error, you have likely tried to move data that isn’t Copy into two different closures. You can fix this issue by making your data Copy or calling clone on it before you move it into the closure.
Broken component:
// `MyComponent` accepts a string which cannot be copied implicitly
#[component]
fn MyComponent(string: String) -> Element {
rsx! {
button {
// ❌ We are moving the string into the onclick handler which means we can't access it elsewhere
onclick: move |_| {
println!("{string}");
},
"Print hello world"
}
button {
// ❌ Since we already moved the string, we can't move it into the onclick handler again. This will cause a compiler error
onclick: move |_| {
println!("{string}");
},
"Print hello world again"
}
}
}You can fix this issue by either:
- Making your data
CopywithReadSignal:
// `MyComponent` accepts `ReadSignal<String>` which implements `Copy`
#[component]
fn MyComponent(string: ReadSignal<String>) -> Element {
rsx! {
button {
// ✅ Because the `string` signal is `Copy`, we can copy it into the closure while still having access to it elsewhere
onclick: move |_| println!("{}", string),
"Print hello world"
}
button {
// ✅ Since `string` is `Copy`, we can move it into the onclick handler again
onclick: move |_| println!("{}", string),
"Print hello world again"
}
}
}- Calling
cloneon your data before you move it into the closure:
// `MyComponent` accepts a string which doesn't implement `Copy`
#[component]
fn MyComponent(string: String) -> Element {
rsx! {
button {
// ✅ The string only has one owner. We could move it into this closure, but since we want to use the string in other closures later, we will clone it instead
onclick: {
// Clone the string in a new block
let string = string.clone();
// Then move the cloned string into the closure
move |_| println!("{}", string)
},
"Print hello world"
}
button {
// ✅ We don't use the string after this closure, so we can just move it into the closure directly
onclick: move |_| println!("{}", string),
"Print hello world again"
}
}
}Sourcefn onfocusin<__Marker>(
self,
event_handler: impl EventHandlerValue<FocusData, __Marker>,
) -> <Self as AttributeBuilderTarget>::Output
fn onfocusin<__Marker>( self, event_handler: impl EventHandlerValue<FocusData, __Marker>, ) -> <Self as AttributeBuilderTarget>::Output
onfocusin
General Event Handler Information
§Event Handlers
Event Handlers let you react to user input in your application. In Dioxus, event handlers accept a closure that is called when the event occurs:
use dioxus::prelude::*;
fn App() -> Element {
rsx! {
button {
// The `onclick` event accepts a closure with the signature `fn(Event)`
onclick: |event_data| println!("clicked! I got the event data: {event_data:?}"),
"Click me"
}
}
}§Event Lifetimes
Events take a closure with the 'static lifetime. This means that the closure can only access data that either exists for the entire lifetime of the application, or data that you move into the closure.
State in dioxus is copy which makes it very easy to move into 'static closures like event handlers:
let mut count = use_signal(|| 0);
rsx! {
button {
// Since we added the `move` keyword, the closure will move the `count` signal into the closure
onclick: move |_| {
// This will panic because the `count` signal is not in scope
count.set(count() + 1);
},
"Click me"
}
};If you need to access data that is not Copy, you may need to clone the data before you move it into the closure:
// String is not `Copy`
let string = "hello world".to_string();
rsx! {
button {
// The string only has one owner. We could move it into this closure, but since we want to use the string in other closures later, we will clone it instead
onclick: {
// Clone the string in a new block
let string = string.clone();
// Then move the cloned string into the closure
move |_| println!("{}", string)
},
"Print hello world"
}
button {
// We don't use the string after this closure, so we can just move it into the closure directly
onclick: move |_| println!("{}", string),
"Print hello world again"
}
};§Async Event Handlers
In addition to closures that return nothing, you can also use async closures to handle events. If you return an async block from an event handler, dioxus will automatically spawn it:
use dioxus::prelude::*;
fn App() -> Element {
rsx! {
button {
// The `onclick` event can also accept a closure that returns an async block
onclick: move |_| async move {
tokio::time::sleep(std::time::Duration::from_secs(1)).await;
println!("You clicked the button one second ago!");
},
"Click me"
}
}
}§Compiler errors you may run into while using event handlers
function requires argument type to outlive `'static`
Event handler in Dioxus need only access data that can last for the entire lifetime of the application. That generally means data that is moved into the closure. If you get this error, you may have forgotten to add move to your closure.
Broken component:
// We return an Element which can last as long as the component is on the screen
fn App() -> Element {
// Signals are `Copy` which makes them very easy to move into `'static` closures like event handlers
let state = use_signal(|| "hello world".to_string());
rsx! {
button {
// ❌ Without `move`, rust will try to borrow the `state` signal which fails because the state signal is dropped at the end of the function
onclick: |_| {
println!("You clicked the button! The state is: {state}");
},
"Click me"
}
}
// The state signal is dropped here, but the event handler still needs to access it
}Fixed component:
fn App() -> Element {
let state = use_signal(|| "hello world".to_string());
rsx! {
button {
// ✅ The `move` keyword tells rust it can move the `state` signal into the closure. Since the closure owns the signal state, it can read it even after the function returns
onclick: move |_| {
println!("You clicked the button! The state is: {state}");
},
"Click me"
}
}
}use of moved value: `your_value` value used here after move
Data in rust has a single owner. If you run into this error, you have likely tried to move data that isn’t Copy into two different closures. You can fix this issue by making your data Copy or calling clone on it before you move it into the closure.
Broken component:
// `MyComponent` accepts a string which cannot be copied implicitly
#[component]
fn MyComponent(string: String) -> Element {
rsx! {
button {
// ❌ We are moving the string into the onclick handler which means we can't access it elsewhere
onclick: move |_| {
println!("{string}");
},
"Print hello world"
}
button {
// ❌ Since we already moved the string, we can't move it into the onclick handler again. This will cause a compiler error
onclick: move |_| {
println!("{string}");
},
"Print hello world again"
}
}
}You can fix this issue by either:
- Making your data
CopywithReadSignal:
// `MyComponent` accepts `ReadSignal<String>` which implements `Copy`
#[component]
fn MyComponent(string: ReadSignal<String>) -> Element {
rsx! {
button {
// ✅ Because the `string` signal is `Copy`, we can copy it into the closure while still having access to it elsewhere
onclick: move |_| println!("{}", string),
"Print hello world"
}
button {
// ✅ Since `string` is `Copy`, we can move it into the onclick handler again
onclick: move |_| println!("{}", string),
"Print hello world again"
}
}
}- Calling
cloneon your data before you move it into the closure:
// `MyComponent` accepts a string which doesn't implement `Copy`
#[component]
fn MyComponent(string: String) -> Element {
rsx! {
button {
// ✅ The string only has one owner. We could move it into this closure, but since we want to use the string in other closures later, we will clone it instead
onclick: {
// Clone the string in a new block
let string = string.clone();
// Then move the cloned string into the closure
move |_| println!("{}", string)
},
"Print hello world"
}
button {
// ✅ We don't use the string after this closure, so we can just move it into the closure directly
onclick: move |_| println!("{}", string),
"Print hello world again"
}
}
}Sourcefn onblur<__Marker>(
self,
event_handler: impl EventHandlerValue<FocusData, __Marker>,
) -> <Self as AttributeBuilderTarget>::Output
fn onblur<__Marker>( self, event_handler: impl EventHandlerValue<FocusData, __Marker>, ) -> <Self as AttributeBuilderTarget>::Output
onblur
General Event Handler Information
§Event Handlers
Event Handlers let you react to user input in your application. In Dioxus, event handlers accept a closure that is called when the event occurs:
use dioxus::prelude::*;
fn App() -> Element {
rsx! {
button {
// The `onclick` event accepts a closure with the signature `fn(Event)`
onclick: |event_data| println!("clicked! I got the event data: {event_data:?}"),
"Click me"
}
}
}§Event Lifetimes
Events take a closure with the 'static lifetime. This means that the closure can only access data that either exists for the entire lifetime of the application, or data that you move into the closure.
State in dioxus is copy which makes it very easy to move into 'static closures like event handlers:
let mut count = use_signal(|| 0);
rsx! {
button {
// Since we added the `move` keyword, the closure will move the `count` signal into the closure
onclick: move |_| {
// This will panic because the `count` signal is not in scope
count.set(count() + 1);
},
"Click me"
}
};If you need to access data that is not Copy, you may need to clone the data before you move it into the closure:
// String is not `Copy`
let string = "hello world".to_string();
rsx! {
button {
// The string only has one owner. We could move it into this closure, but since we want to use the string in other closures later, we will clone it instead
onclick: {
// Clone the string in a new block
let string = string.clone();
// Then move the cloned string into the closure
move |_| println!("{}", string)
},
"Print hello world"
}
button {
// We don't use the string after this closure, so we can just move it into the closure directly
onclick: move |_| println!("{}", string),
"Print hello world again"
}
};§Async Event Handlers
In addition to closures that return nothing, you can also use async closures to handle events. If you return an async block from an event handler, dioxus will automatically spawn it:
use dioxus::prelude::*;
fn App() -> Element {
rsx! {
button {
// The `onclick` event can also accept a closure that returns an async block
onclick: move |_| async move {
tokio::time::sleep(std::time::Duration::from_secs(1)).await;
println!("You clicked the button one second ago!");
},
"Click me"
}
}
}§Compiler errors you may run into while using event handlers
function requires argument type to outlive `'static`
Event handler in Dioxus need only access data that can last for the entire lifetime of the application. That generally means data that is moved into the closure. If you get this error, you may have forgotten to add move to your closure.
Broken component:
// We return an Element which can last as long as the component is on the screen
fn App() -> Element {
// Signals are `Copy` which makes them very easy to move into `'static` closures like event handlers
let state = use_signal(|| "hello world".to_string());
rsx! {
button {
// ❌ Without `move`, rust will try to borrow the `state` signal which fails because the state signal is dropped at the end of the function
onclick: |_| {
println!("You clicked the button! The state is: {state}");
},
"Click me"
}
}
// The state signal is dropped here, but the event handler still needs to access it
}Fixed component:
fn App() -> Element {
let state = use_signal(|| "hello world".to_string());
rsx! {
button {
// ✅ The `move` keyword tells rust it can move the `state` signal into the closure. Since the closure owns the signal state, it can read it even after the function returns
onclick: move |_| {
println!("You clicked the button! The state is: {state}");
},
"Click me"
}
}
}use of moved value: `your_value` value used here after move
Data in rust has a single owner. If you run into this error, you have likely tried to move data that isn’t Copy into two different closures. You can fix this issue by making your data Copy or calling clone on it before you move it into the closure.
Broken component:
// `MyComponent` accepts a string which cannot be copied implicitly
#[component]
fn MyComponent(string: String) -> Element {
rsx! {
button {
// ❌ We are moving the string into the onclick handler which means we can't access it elsewhere
onclick: move |_| {
println!("{string}");
},
"Print hello world"
}
button {
// ❌ Since we already moved the string, we can't move it into the onclick handler again. This will cause a compiler error
onclick: move |_| {
println!("{string}");
},
"Print hello world again"
}
}
}You can fix this issue by either:
- Making your data
CopywithReadSignal:
// `MyComponent` accepts `ReadSignal<String>` which implements `Copy`
#[component]
fn MyComponent(string: ReadSignal<String>) -> Element {
rsx! {
button {
// ✅ Because the `string` signal is `Copy`, we can copy it into the closure while still having access to it elsewhere
onclick: move |_| println!("{}", string),
"Print hello world"
}
button {
// ✅ Since `string` is `Copy`, we can move it into the onclick handler again
onclick: move |_| println!("{}", string),
"Print hello world again"
}
}
}- Calling
cloneon your data before you move it into the closure:
// `MyComponent` accepts a string which doesn't implement `Copy`
#[component]
fn MyComponent(string: String) -> Element {
rsx! {
button {
// ✅ The string only has one owner. We could move it into this closure, but since we want to use the string in other closures later, we will clone it instead
onclick: {
// Clone the string in a new block
let string = string.clone();
// Then move the cloned string into the closure
move |_| println!("{}", string)
},
"Print hello world"
}
button {
// ✅ We don't use the string after this closure, so we can just move it into the closure directly
onclick: move |_| println!("{}", string),
"Print hello world again"
}
}
}Sourcefn onchange<__Marker>(
self,
event_handler: impl EventHandlerValue<FormData, __Marker>,
) -> <Self as AttributeBuilderTarget>::Output
fn onchange<__Marker>( self, event_handler: impl EventHandlerValue<FormData, __Marker>, ) -> <Self as AttributeBuilderTarget>::Output
onchange
General Event Handler Information
§Event Handlers
Event Handlers let you react to user input in your application. In Dioxus, event handlers accept a closure that is called when the event occurs:
use dioxus::prelude::*;
fn App() -> Element {
rsx! {
button {
// The `onclick` event accepts a closure with the signature `fn(Event)`
onclick: |event_data| println!("clicked! I got the event data: {event_data:?}"),
"Click me"
}
}
}§Event Lifetimes
Events take a closure with the 'static lifetime. This means that the closure can only access data that either exists for the entire lifetime of the application, or data that you move into the closure.
State in dioxus is copy which makes it very easy to move into 'static closures like event handlers:
let mut count = use_signal(|| 0);
rsx! {
button {
// Since we added the `move` keyword, the closure will move the `count` signal into the closure
onclick: move |_| {
// This will panic because the `count` signal is not in scope
count.set(count() + 1);
},
"Click me"
}
};If you need to access data that is not Copy, you may need to clone the data before you move it into the closure:
// String is not `Copy`
let string = "hello world".to_string();
rsx! {
button {
// The string only has one owner. We could move it into this closure, but since we want to use the string in other closures later, we will clone it instead
onclick: {
// Clone the string in a new block
let string = string.clone();
// Then move the cloned string into the closure
move |_| println!("{}", string)
},
"Print hello world"
}
button {
// We don't use the string after this closure, so we can just move it into the closure directly
onclick: move |_| println!("{}", string),
"Print hello world again"
}
};§Async Event Handlers
In addition to closures that return nothing, you can also use async closures to handle events. If you return an async block from an event handler, dioxus will automatically spawn it:
use dioxus::prelude::*;
fn App() -> Element {
rsx! {
button {
// The `onclick` event can also accept a closure that returns an async block
onclick: move |_| async move {
tokio::time::sleep(std::time::Duration::from_secs(1)).await;
println!("You clicked the button one second ago!");
},
"Click me"
}
}
}§Compiler errors you may run into while using event handlers
function requires argument type to outlive `'static`
Event handler in Dioxus need only access data that can last for the entire lifetime of the application. That generally means data that is moved into the closure. If you get this error, you may have forgotten to add move to your closure.
Broken component:
// We return an Element which can last as long as the component is on the screen
fn App() -> Element {
// Signals are `Copy` which makes them very easy to move into `'static` closures like event handlers
let state = use_signal(|| "hello world".to_string());
rsx! {
button {
// ❌ Without `move`, rust will try to borrow the `state` signal which fails because the state signal is dropped at the end of the function
onclick: |_| {
println!("You clicked the button! The state is: {state}");
},
"Click me"
}
}
// The state signal is dropped here, but the event handler still needs to access it
}Fixed component:
fn App() -> Element {
let state = use_signal(|| "hello world".to_string());
rsx! {
button {
// ✅ The `move` keyword tells rust it can move the `state` signal into the closure. Since the closure owns the signal state, it can read it even after the function returns
onclick: move |_| {
println!("You clicked the button! The state is: {state}");
},
"Click me"
}
}
}use of moved value: `your_value` value used here after move
Data in rust has a single owner. If you run into this error, you have likely tried to move data that isn’t Copy into two different closures. You can fix this issue by making your data Copy or calling clone on it before you move it into the closure.
Broken component:
// `MyComponent` accepts a string which cannot be copied implicitly
#[component]
fn MyComponent(string: String) -> Element {
rsx! {
button {
// ❌ We are moving the string into the onclick handler which means we can't access it elsewhere
onclick: move |_| {
println!("{string}");
},
"Print hello world"
}
button {
// ❌ Since we already moved the string, we can't move it into the onclick handler again. This will cause a compiler error
onclick: move |_| {
println!("{string}");
},
"Print hello world again"
}
}
}You can fix this issue by either:
- Making your data
CopywithReadSignal:
// `MyComponent` accepts `ReadSignal<String>` which implements `Copy`
#[component]
fn MyComponent(string: ReadSignal<String>) -> Element {
rsx! {
button {
// ✅ Because the `string` signal is `Copy`, we can copy it into the closure while still having access to it elsewhere
onclick: move |_| println!("{}", string),
"Print hello world"
}
button {
// ✅ Since `string` is `Copy`, we can move it into the onclick handler again
onclick: move |_| println!("{}", string),
"Print hello world again"
}
}
}- Calling
cloneon your data before you move it into the closure:
// `MyComponent` accepts a string which doesn't implement `Copy`
#[component]
fn MyComponent(string: String) -> Element {
rsx! {
button {
// ✅ The string only has one owner. We could move it into this closure, but since we want to use the string in other closures later, we will clone it instead
onclick: {
// Clone the string in a new block
let string = string.clone();
// Then move the cloned string into the closure
move |_| println!("{}", string)
},
"Print hello world"
}
button {
// ✅ We don't use the string after this closure, so we can just move it into the closure directly
onclick: move |_| println!("{}", string),
"Print hello world again"
}
}
}Sourcefn oninput<__Marker>(
self,
event_handler: impl EventHandlerValue<FormData, __Marker>,
) -> <Self as AttributeBuilderTarget>::Output
fn oninput<__Marker>( self, event_handler: impl EventHandlerValue<FormData, __Marker>, ) -> <Self as AttributeBuilderTarget>::Output
oninput
The oninput event is fired when the value of a <input>, <select>, or <textarea> element is changed.
There are two main approaches to updating your input element:
- Controlled inputs directly update the value of the input element as the user interacts with the element
use dioxus::prelude::*;
fn App() -> Element {
let mut value = use_signal(|| "hello world".to_string());
rsx! {
input {
value: "{value}",
oninput: move |event| value.set(event.value())
}
button {
onclick: move |_| value.write().clear(),
"Clear"
}
}
}- Uncontrolled inputs just read the value of the input element as it changes
use dioxus::prelude::*;
fn App() -> Element {
rsx! {
input {
oninput: move |event| println!("{}", event.value()),
}
}
}General Event Handler Information
§Event Handlers
Event Handlers let you react to user input in your application. In Dioxus, event handlers accept a closure that is called when the event occurs:
use dioxus::prelude::*;
fn App() -> Element {
rsx! {
button {
// The `onclick` event accepts a closure with the signature `fn(Event)`
onclick: |event_data| println!("clicked! I got the event data: {event_data:?}"),
"Click me"
}
}
}§Event Lifetimes
Events take a closure with the 'static lifetime. This means that the closure can only access data that either exists for the entire lifetime of the application, or data that you move into the closure.
State in dioxus is copy which makes it very easy to move into 'static closures like event handlers:
let mut count = use_signal(|| 0);
rsx! {
button {
// Since we added the `move` keyword, the closure will move the `count` signal into the closure
onclick: move |_| {
// This will panic because the `count` signal is not in scope
count.set(count() + 1);
},
"Click me"
}
};If you need to access data that is not Copy, you may need to clone the data before you move it into the closure:
// String is not `Copy`
let string = "hello world".to_string();
rsx! {
button {
// The string only has one owner. We could move it into this closure, but since we want to use the string in other closures later, we will clone it instead
onclick: {
// Clone the string in a new block
let string = string.clone();
// Then move the cloned string into the closure
move |_| println!("{}", string)
},
"Print hello world"
}
button {
// We don't use the string after this closure, so we can just move it into the closure directly
onclick: move |_| println!("{}", string),
"Print hello world again"
}
};§Async Event Handlers
In addition to closures that return nothing, you can also use async closures to handle events. If you return an async block from an event handler, dioxus will automatically spawn it:
use dioxus::prelude::*;
fn App() -> Element {
rsx! {
button {
// The `onclick` event can also accept a closure that returns an async block
onclick: move |_| async move {
tokio::time::sleep(std::time::Duration::from_secs(1)).await;
println!("You clicked the button one second ago!");
},
"Click me"
}
}
}§Compiler errors you may run into while using event handlers
function requires argument type to outlive `'static`
Event handler in Dioxus need only access data that can last for the entire lifetime of the application. That generally means data that is moved into the closure. If you get this error, you may have forgotten to add move to your closure.
Broken component:
// We return an Element which can last as long as the component is on the screen
fn App() -> Element {
// Signals are `Copy` which makes them very easy to move into `'static` closures like event handlers
let state = use_signal(|| "hello world".to_string());
rsx! {
button {
// ❌ Without `move`, rust will try to borrow the `state` signal which fails because the state signal is dropped at the end of the function
onclick: |_| {
println!("You clicked the button! The state is: {state}");
},
"Click me"
}
}
// The state signal is dropped here, but the event handler still needs to access it
}Fixed component:
fn App() -> Element {
let state = use_signal(|| "hello world".to_string());
rsx! {
button {
// ✅ The `move` keyword tells rust it can move the `state` signal into the closure. Since the closure owns the signal state, it can read it even after the function returns
onclick: move |_| {
println!("You clicked the button! The state is: {state}");
},
"Click me"
}
}
}use of moved value: `your_value` value used here after move
Data in rust has a single owner. If you run into this error, you have likely tried to move data that isn’t Copy into two different closures. You can fix this issue by making your data Copy or calling clone on it before you move it into the closure.
Broken component:
// `MyComponent` accepts a string which cannot be copied implicitly
#[component]
fn MyComponent(string: String) -> Element {
rsx! {
button {
// ❌ We are moving the string into the onclick handler which means we can't access it elsewhere
onclick: move |_| {
println!("{string}");
},
"Print hello world"
}
button {
// ❌ Since we already moved the string, we can't move it into the onclick handler again. This will cause a compiler error
onclick: move |_| {
println!("{string}");
},
"Print hello world again"
}
}
}You can fix this issue by either:
- Making your data
CopywithReadSignal:
// `MyComponent` accepts `ReadSignal<String>` which implements `Copy`
#[component]
fn MyComponent(string: ReadSignal<String>) -> Element {
rsx! {
button {
// ✅ Because the `string` signal is `Copy`, we can copy it into the closure while still having access to it elsewhere
onclick: move |_| println!("{}", string),
"Print hello world"
}
button {
// ✅ Since `string` is `Copy`, we can move it into the onclick handler again
onclick: move |_| println!("{}", string),
"Print hello world again"
}
}
}- Calling
cloneon your data before you move it into the closure:
// `MyComponent` accepts a string which doesn't implement `Copy`
#[component]
fn MyComponent(string: String) -> Element {
rsx! {
button {
// ✅ The string only has one owner. We could move it into this closure, but since we want to use the string in other closures later, we will clone it instead
onclick: {
// Clone the string in a new block
let string = string.clone();
// Then move the cloned string into the closure
move |_| println!("{}", string)
},
"Print hello world"
}
button {
// ✅ We don't use the string after this closure, so we can just move it into the closure directly
onclick: move |_| println!("{}", string),
"Print hello world again"
}
}
}Sourcefn oninvalid<__Marker>(
self,
event_handler: impl EventHandlerValue<FormData, __Marker>,
) -> <Self as AttributeBuilderTarget>::Output
fn oninvalid<__Marker>( self, event_handler: impl EventHandlerValue<FormData, __Marker>, ) -> <Self as AttributeBuilderTarget>::Output
oninvalid
General Event Handler Information
§Event Handlers
Event Handlers let you react to user input in your application. In Dioxus, event handlers accept a closure that is called when the event occurs:
use dioxus::prelude::*;
fn App() -> Element {
rsx! {
button {
// The `onclick` event accepts a closure with the signature `fn(Event)`
onclick: |event_data| println!("clicked! I got the event data: {event_data:?}"),
"Click me"
}
}
}§Event Lifetimes
Events take a closure with the 'static lifetime. This means that the closure can only access data that either exists for the entire lifetime of the application, or data that you move into the closure.
State in dioxus is copy which makes it very easy to move into 'static closures like event handlers:
let mut count = use_signal(|| 0);
rsx! {
button {
// Since we added the `move` keyword, the closure will move the `count` signal into the closure
onclick: move |_| {
// This will panic because the `count` signal is not in scope
count.set(count() + 1);
},
"Click me"
}
};If you need to access data that is not Copy, you may need to clone the data before you move it into the closure:
// String is not `Copy`
let string = "hello world".to_string();
rsx! {
button {
// The string only has one owner. We could move it into this closure, but since we want to use the string in other closures later, we will clone it instead
onclick: {
// Clone the string in a new block
let string = string.clone();
// Then move the cloned string into the closure
move |_| println!("{}", string)
},
"Print hello world"
}
button {
// We don't use the string after this closure, so we can just move it into the closure directly
onclick: move |_| println!("{}", string),
"Print hello world again"
}
};§Async Event Handlers
In addition to closures that return nothing, you can also use async closures to handle events. If you return an async block from an event handler, dioxus will automatically spawn it:
use dioxus::prelude::*;
fn App() -> Element {
rsx! {
button {
// The `onclick` event can also accept a closure that returns an async block
onclick: move |_| async move {
tokio::time::sleep(std::time::Duration::from_secs(1)).await;
println!("You clicked the button one second ago!");
},
"Click me"
}
}
}§Compiler errors you may run into while using event handlers
function requires argument type to outlive `'static`
Event handler in Dioxus need only access data that can last for the entire lifetime of the application. That generally means data that is moved into the closure. If you get this error, you may have forgotten to add move to your closure.
Broken component:
// We return an Element which can last as long as the component is on the screen
fn App() -> Element {
// Signals are `Copy` which makes them very easy to move into `'static` closures like event handlers
let state = use_signal(|| "hello world".to_string());
rsx! {
button {
// ❌ Without `move`, rust will try to borrow the `state` signal which fails because the state signal is dropped at the end of the function
onclick: |_| {
println!("You clicked the button! The state is: {state}");
},
"Click me"
}
}
// The state signal is dropped here, but the event handler still needs to access it
}Fixed component:
fn App() -> Element {
let state = use_signal(|| "hello world".to_string());
rsx! {
button {
// ✅ The `move` keyword tells rust it can move the `state` signal into the closure. Since the closure owns the signal state, it can read it even after the function returns
onclick: move |_| {
println!("You clicked the button! The state is: {state}");
},
"Click me"
}
}
}use of moved value: `your_value` value used here after move
Data in rust has a single owner. If you run into this error, you have likely tried to move data that isn’t Copy into two different closures. You can fix this issue by making your data Copy or calling clone on it before you move it into the closure.
Broken component:
// `MyComponent` accepts a string which cannot be copied implicitly
#[component]
fn MyComponent(string: String) -> Element {
rsx! {
button {
// ❌ We are moving the string into the onclick handler which means we can't access it elsewhere
onclick: move |_| {
println!("{string}");
},
"Print hello world"
}
button {
// ❌ Since we already moved the string, we can't move it into the onclick handler again. This will cause a compiler error
onclick: move |_| {
println!("{string}");
},
"Print hello world again"
}
}
}You can fix this issue by either:
- Making your data
CopywithReadSignal:
// `MyComponent` accepts `ReadSignal<String>` which implements `Copy`
#[component]
fn MyComponent(string: ReadSignal<String>) -> Element {
rsx! {
button {
// ✅ Because the `string` signal is `Copy`, we can copy it into the closure while still having access to it elsewhere
onclick: move |_| println!("{}", string),
"Print hello world"
}
button {
// ✅ Since `string` is `Copy`, we can move it into the onclick handler again
onclick: move |_| println!("{}", string),
"Print hello world again"
}
}
}- Calling
cloneon your data before you move it into the closure:
// `MyComponent` accepts a string which doesn't implement `Copy`
#[component]
fn MyComponent(string: String) -> Element {
rsx! {
button {
// ✅ The string only has one owner. We could move it into this closure, but since we want to use the string in other closures later, we will clone it instead
onclick: {
// Clone the string in a new block
let string = string.clone();
// Then move the cloned string into the closure
move |_| println!("{}", string)
},
"Print hello world"
}
button {
// ✅ We don't use the string after this closure, so we can just move it into the closure directly
onclick: move |_| println!("{}", string),
"Print hello world again"
}
}
}Sourcefn onreset<__Marker>(
self,
event_handler: impl EventHandlerValue<FormData, __Marker>,
) -> <Self as AttributeBuilderTarget>::Output
fn onreset<__Marker>( self, event_handler: impl EventHandlerValue<FormData, __Marker>, ) -> <Self as AttributeBuilderTarget>::Output
onreset
General Event Handler Information
§Event Handlers
Event Handlers let you react to user input in your application. In Dioxus, event handlers accept a closure that is called when the event occurs:
use dioxus::prelude::*;
fn App() -> Element {
rsx! {
button {
// The `onclick` event accepts a closure with the signature `fn(Event)`
onclick: |event_data| println!("clicked! I got the event data: {event_data:?}"),
"Click me"
}
}
}§Event Lifetimes
Events take a closure with the 'static lifetime. This means that the closure can only access data that either exists for the entire lifetime of the application, or data that you move into the closure.
State in dioxus is copy which makes it very easy to move into 'static closures like event handlers:
let mut count = use_signal(|| 0);
rsx! {
button {
// Since we added the `move` keyword, the closure will move the `count` signal into the closure
onclick: move |_| {
// This will panic because the `count` signal is not in scope
count.set(count() + 1);
},
"Click me"
}
};If you need to access data that is not Copy, you may need to clone the data before you move it into the closure:
// String is not `Copy`
let string = "hello world".to_string();
rsx! {
button {
// The string only has one owner. We could move it into this closure, but since we want to use the string in other closures later, we will clone it instead
onclick: {
// Clone the string in a new block
let string = string.clone();
// Then move the cloned string into the closure
move |_| println!("{}", string)
},
"Print hello world"
}
button {
// We don't use the string after this closure, so we can just move it into the closure directly
onclick: move |_| println!("{}", string),
"Print hello world again"
}
};§Async Event Handlers
In addition to closures that return nothing, you can also use async closures to handle events. If you return an async block from an event handler, dioxus will automatically spawn it:
use dioxus::prelude::*;
fn App() -> Element {
rsx! {
button {
// The `onclick` event can also accept a closure that returns an async block
onclick: move |_| async move {
tokio::time::sleep(std::time::Duration::from_secs(1)).await;
println!("You clicked the button one second ago!");
},
"Click me"
}
}
}§Compiler errors you may run into while using event handlers
function requires argument type to outlive `'static`
Event handler in Dioxus need only access data that can last for the entire lifetime of the application. That generally means data that is moved into the closure. If you get this error, you may have forgotten to add move to your closure.
Broken component:
// We return an Element which can last as long as the component is on the screen
fn App() -> Element {
// Signals are `Copy` which makes them very easy to move into `'static` closures like event handlers
let state = use_signal(|| "hello world".to_string());
rsx! {
button {
// ❌ Without `move`, rust will try to borrow the `state` signal which fails because the state signal is dropped at the end of the function
onclick: |_| {
println!("You clicked the button! The state is: {state}");
},
"Click me"
}
}
// The state signal is dropped here, but the event handler still needs to access it
}Fixed component:
fn App() -> Element {
let state = use_signal(|| "hello world".to_string());
rsx! {
button {
// ✅ The `move` keyword tells rust it can move the `state` signal into the closure. Since the closure owns the signal state, it can read it even after the function returns
onclick: move |_| {
println!("You clicked the button! The state is: {state}");
},
"Click me"
}
}
}use of moved value: `your_value` value used here after move
Data in rust has a single owner. If you run into this error, you have likely tried to move data that isn’t Copy into two different closures. You can fix this issue by making your data Copy or calling clone on it before you move it into the closure.
Broken component:
// `MyComponent` accepts a string which cannot be copied implicitly
#[component]
fn MyComponent(string: String) -> Element {
rsx! {
button {
// ❌ We are moving the string into the onclick handler which means we can't access it elsewhere
onclick: move |_| {
println!("{string}");
},
"Print hello world"
}
button {
// ❌ Since we already moved the string, we can't move it into the onclick handler again. This will cause a compiler error
onclick: move |_| {
println!("{string}");
},
"Print hello world again"
}
}
}You can fix this issue by either:
- Making your data
CopywithReadSignal:
// `MyComponent` accepts `ReadSignal<String>` which implements `Copy`
#[component]
fn MyComponent(string: ReadSignal<String>) -> Element {
rsx! {
button {
// ✅ Because the `string` signal is `Copy`, we can copy it into the closure while still having access to it elsewhere
onclick: move |_| println!("{}", string),
"Print hello world"
}
button {
// ✅ Since `string` is `Copy`, we can move it into the onclick handler again
onclick: move |_| println!("{}", string),
"Print hello world again"
}
}
}- Calling
cloneon your data before you move it into the closure:
// `MyComponent` accepts a string which doesn't implement `Copy`
#[component]
fn MyComponent(string: String) -> Element {
rsx! {
button {
// ✅ The string only has one owner. We could move it into this closure, but since we want to use the string in other closures later, we will clone it instead
onclick: {
// Clone the string in a new block
let string = string.clone();
// Then move the cloned string into the closure
move |_| println!("{}", string)
},
"Print hello world"
}
button {
// ✅ We don't use the string after this closure, so we can just move it into the closure directly
onclick: move |_| println!("{}", string),
"Print hello world again"
}
}
}Sourcefn onsubmit<__Marker>(
self,
event_handler: impl EventHandlerValue<FormData, __Marker>,
) -> <Self as AttributeBuilderTarget>::Output
fn onsubmit<__Marker>( self, event_handler: impl EventHandlerValue<FormData, __Marker>, ) -> <Self as AttributeBuilderTarget>::Output
onsubmit
General Event Handler Information
§Event Handlers
Event Handlers let you react to user input in your application. In Dioxus, event handlers accept a closure that is called when the event occurs:
use dioxus::prelude::*;
fn App() -> Element {
rsx! {
button {
// The `onclick` event accepts a closure with the signature `fn(Event)`
onclick: |event_data| println!("clicked! I got the event data: {event_data:?}"),
"Click me"
}
}
}§Event Lifetimes
Events take a closure with the 'static lifetime. This means that the closure can only access data that either exists for the entire lifetime of the application, or data that you move into the closure.
State in dioxus is copy which makes it very easy to move into 'static closures like event handlers:
let mut count = use_signal(|| 0);
rsx! {
button {
// Since we added the `move` keyword, the closure will move the `count` signal into the closure
onclick: move |_| {
// This will panic because the `count` signal is not in scope
count.set(count() + 1);
},
"Click me"
}
};If you need to access data that is not Copy, you may need to clone the data before you move it into the closure:
// String is not `Copy`
let string = "hello world".to_string();
rsx! {
button {
// The string only has one owner. We could move it into this closure, but since we want to use the string in other closures later, we will clone it instead
onclick: {
// Clone the string in a new block
let string = string.clone();
// Then move the cloned string into the closure
move |_| println!("{}", string)
},
"Print hello world"
}
button {
// We don't use the string after this closure, so we can just move it into the closure directly
onclick: move |_| println!("{}", string),
"Print hello world again"
}
};§Async Event Handlers
In addition to closures that return nothing, you can also use async closures to handle events. If you return an async block from an event handler, dioxus will automatically spawn it:
use dioxus::prelude::*;
fn App() -> Element {
rsx! {
button {
// The `onclick` event can also accept a closure that returns an async block
onclick: move |_| async move {
tokio::time::sleep(std::time::Duration::from_secs(1)).await;
println!("You clicked the button one second ago!");
},
"Click me"
}
}
}§Compiler errors you may run into while using event handlers
function requires argument type to outlive `'static`
Event handler in Dioxus need only access data that can last for the entire lifetime of the application. That generally means data that is moved into the closure. If you get this error, you may have forgotten to add move to your closure.
Broken component:
// We return an Element which can last as long as the component is on the screen
fn App() -> Element {
// Signals are `Copy` which makes them very easy to move into `'static` closures like event handlers
let state = use_signal(|| "hello world".to_string());
rsx! {
button {
// ❌ Without `move`, rust will try to borrow the `state` signal which fails because the state signal is dropped at the end of the function
onclick: |_| {
println!("You clicked the button! The state is: {state}");
},
"Click me"
}
}
// The state signal is dropped here, but the event handler still needs to access it
}Fixed component:
fn App() -> Element {
let state = use_signal(|| "hello world".to_string());
rsx! {
button {
// ✅ The `move` keyword tells rust it can move the `state` signal into the closure. Since the closure owns the signal state, it can read it even after the function returns
onclick: move |_| {
println!("You clicked the button! The state is: {state}");
},
"Click me"
}
}
}use of moved value: `your_value` value used here after move
Data in rust has a single owner. If you run into this error, you have likely tried to move data that isn’t Copy into two different closures. You can fix this issue by making your data Copy or calling clone on it before you move it into the closure.
Broken component:
// `MyComponent` accepts a string which cannot be copied implicitly
#[component]
fn MyComponent(string: String) -> Element {
rsx! {
button {
// ❌ We are moving the string into the onclick handler which means we can't access it elsewhere
onclick: move |_| {
println!("{string}");
},
"Print hello world"
}
button {
// ❌ Since we already moved the string, we can't move it into the onclick handler again. This will cause a compiler error
onclick: move |_| {
println!("{string}");
},
"Print hello world again"
}
}
}You can fix this issue by either:
- Making your data
CopywithReadSignal:
// `MyComponent` accepts `ReadSignal<String>` which implements `Copy`
#[component]
fn MyComponent(string: ReadSignal<String>) -> Element {
rsx! {
button {
// ✅ Because the `string` signal is `Copy`, we can copy it into the closure while still having access to it elsewhere
onclick: move |_| println!("{}", string),
"Print hello world"
}
button {
// ✅ Since `string` is `Copy`, we can move it into the onclick handler again
onclick: move |_| println!("{}", string),
"Print hello world again"
}
}
}- Calling
cloneon your data before you move it into the closure:
// `MyComponent` accepts a string which doesn't implement `Copy`
#[component]
fn MyComponent(string: String) -> Element {
rsx! {
button {
// ✅ The string only has one owner. We could move it into this closure, but since we want to use the string in other closures later, we will clone it instead
onclick: {
// Clone the string in a new block
let string = string.clone();
// Then move the cloned string into the closure
move |_| println!("{}", string)
},
"Print hello world"
}
button {
// ✅ We don't use the string after this closure, so we can just move it into the closure directly
onclick: move |_| println!("{}", string),
"Print hello world again"
}
}
}Sourcefn onerror<__Marker>(
self,
event_handler: impl EventHandlerValue<ImageData, __Marker>,
) -> <Self as AttributeBuilderTarget>::Output
fn onerror<__Marker>( self, event_handler: impl EventHandlerValue<ImageData, __Marker>, ) -> <Self as AttributeBuilderTarget>::Output
onerror
General Event Handler Information
§Event Handlers
Event Handlers let you react to user input in your application. In Dioxus, event handlers accept a closure that is called when the event occurs:
use dioxus::prelude::*;
fn App() -> Element {
rsx! {
button {
// The `onclick` event accepts a closure with the signature `fn(Event)`
onclick: |event_data| println!("clicked! I got the event data: {event_data:?}"),
"Click me"
}
}
}§Event Lifetimes
Events take a closure with the 'static lifetime. This means that the closure can only access data that either exists for the entire lifetime of the application, or data that you move into the closure.
State in dioxus is copy which makes it very easy to move into 'static closures like event handlers:
let mut count = use_signal(|| 0);
rsx! {
button {
// Since we added the `move` keyword, the closure will move the `count` signal into the closure
onclick: move |_| {
// This will panic because the `count` signal is not in scope
count.set(count() + 1);
},
"Click me"
}
};If you need to access data that is not Copy, you may need to clone the data before you move it into the closure:
// String is not `Copy`
let string = "hello world".to_string();
rsx! {
button {
// The string only has one owner. We could move it into this closure, but since we want to use the string in other closures later, we will clone it instead
onclick: {
// Clone the string in a new block
let string = string.clone();
// Then move the cloned string into the closure
move |_| println!("{}", string)
},
"Print hello world"
}
button {
// We don't use the string after this closure, so we can just move it into the closure directly
onclick: move |_| println!("{}", string),
"Print hello world again"
}
};§Async Event Handlers
In addition to closures that return nothing, you can also use async closures to handle events. If you return an async block from an event handler, dioxus will automatically spawn it:
use dioxus::prelude::*;
fn App() -> Element {
rsx! {
button {
// The `onclick` event can also accept a closure that returns an async block
onclick: move |_| async move {
tokio::time::sleep(std::time::Duration::from_secs(1)).await;
println!("You clicked the button one second ago!");
},
"Click me"
}
}
}§Compiler errors you may run into while using event handlers
function requires argument type to outlive `'static`
Event handler in Dioxus need only access data that can last for the entire lifetime of the application. That generally means data that is moved into the closure. If you get this error, you may have forgotten to add move to your closure.
Broken component:
// We return an Element which can last as long as the component is on the screen
fn App() -> Element {
// Signals are `Copy` which makes them very easy to move into `'static` closures like event handlers
let state = use_signal(|| "hello world".to_string());
rsx! {
button {
// ❌ Without `move`, rust will try to borrow the `state` signal which fails because the state signal is dropped at the end of the function
onclick: |_| {
println!("You clicked the button! The state is: {state}");
},
"Click me"
}
}
// The state signal is dropped here, but the event handler still needs to access it
}Fixed component:
fn App() -> Element {
let state = use_signal(|| "hello world".to_string());
rsx! {
button {
// ✅ The `move` keyword tells rust it can move the `state` signal into the closure. Since the closure owns the signal state, it can read it even after the function returns
onclick: move |_| {
println!("You clicked the button! The state is: {state}");
},
"Click me"
}
}
}use of moved value: `your_value` value used here after move
Data in rust has a single owner. If you run into this error, you have likely tried to move data that isn’t Copy into two different closures. You can fix this issue by making your data Copy or calling clone on it before you move it into the closure.
Broken component:
// `MyComponent` accepts a string which cannot be copied implicitly
#[component]
fn MyComponent(string: String) -> Element {
rsx! {
button {
// ❌ We are moving the string into the onclick handler which means we can't access it elsewhere
onclick: move |_| {
println!("{string}");
},
"Print hello world"
}
button {
// ❌ Since we already moved the string, we can't move it into the onclick handler again. This will cause a compiler error
onclick: move |_| {
println!("{string}");
},
"Print hello world again"
}
}
}You can fix this issue by either:
- Making your data
CopywithReadSignal:
// `MyComponent` accepts `ReadSignal<String>` which implements `Copy`
#[component]
fn MyComponent(string: ReadSignal<String>) -> Element {
rsx! {
button {
// ✅ Because the `string` signal is `Copy`, we can copy it into the closure while still having access to it elsewhere
onclick: move |_| println!("{}", string),
"Print hello world"
}
button {
// ✅ Since `string` is `Copy`, we can move it into the onclick handler again
onclick: move |_| println!("{}", string),
"Print hello world again"
}
}
}- Calling
cloneon your data before you move it into the closure:
// `MyComponent` accepts a string which doesn't implement `Copy`
#[component]
fn MyComponent(string: String) -> Element {
rsx! {
button {
// ✅ The string only has one owner. We could move it into this closure, but since we want to use the string in other closures later, we will clone it instead
onclick: {
// Clone the string in a new block
let string = string.clone();
// Then move the cloned string into the closure
move |_| println!("{}", string)
},
"Print hello world"
}
button {
// ✅ We don't use the string after this closure, so we can just move it into the closure directly
onclick: move |_| println!("{}", string),
"Print hello world again"
}
}
}Sourcefn onload<__Marker>(
self,
event_handler: impl EventHandlerValue<ImageData, __Marker>,
) -> <Self as AttributeBuilderTarget>::Output
fn onload<__Marker>( self, event_handler: impl EventHandlerValue<ImageData, __Marker>, ) -> <Self as AttributeBuilderTarget>::Output
onload
General Event Handler Information
§Event Handlers
Event Handlers let you react to user input in your application. In Dioxus, event handlers accept a closure that is called when the event occurs:
use dioxus::prelude::*;
fn App() -> Element {
rsx! {
button {
// The `onclick` event accepts a closure with the signature `fn(Event)`
onclick: |event_data| println!("clicked! I got the event data: {event_data:?}"),
"Click me"
}
}
}§Event Lifetimes
Events take a closure with the 'static lifetime. This means that the closure can only access data that either exists for the entire lifetime of the application, or data that you move into the closure.
State in dioxus is copy which makes it very easy to move into 'static closures like event handlers:
let mut count = use_signal(|| 0);
rsx! {
button {
// Since we added the `move` keyword, the closure will move the `count` signal into the closure
onclick: move |_| {
// This will panic because the `count` signal is not in scope
count.set(count() + 1);
},
"Click me"
}
};If you need to access data that is not Copy, you may need to clone the data before you move it into the closure:
// String is not `Copy`
let string = "hello world".to_string();
rsx! {
button {
// The string only has one owner. We could move it into this closure, but since we want to use the string in other closures later, we will clone it instead
onclick: {
// Clone the string in a new block
let string = string.clone();
// Then move the cloned string into the closure
move |_| println!("{}", string)
},
"Print hello world"
}
button {
// We don't use the string after this closure, so we can just move it into the closure directly
onclick: move |_| println!("{}", string),
"Print hello world again"
}
};§Async Event Handlers
In addition to closures that return nothing, you can also use async closures to handle events. If you return an async block from an event handler, dioxus will automatically spawn it:
use dioxus::prelude::*;
fn App() -> Element {
rsx! {
button {
// The `onclick` event can also accept a closure that returns an async block
onclick: move |_| async move {
tokio::time::sleep(std::time::Duration::from_secs(1)).await;
println!("You clicked the button one second ago!");
},
"Click me"
}
}
}§Compiler errors you may run into while using event handlers
function requires argument type to outlive `'static`
Event handler in Dioxus need only access data that can last for the entire lifetime of the application. That generally means data that is moved into the closure. If you get this error, you may have forgotten to add move to your closure.
Broken component:
// We return an Element which can last as long as the component is on the screen
fn App() -> Element {
// Signals are `Copy` which makes them very easy to move into `'static` closures like event handlers
let state = use_signal(|| "hello world".to_string());
rsx! {
button {
// ❌ Without `move`, rust will try to borrow the `state` signal which fails because the state signal is dropped at the end of the function
onclick: |_| {
println!("You clicked the button! The state is: {state}");
},
"Click me"
}
}
// The state signal is dropped here, but the event handler still needs to access it
}Fixed component:
fn App() -> Element {
let state = use_signal(|| "hello world".to_string());
rsx! {
button {
// ✅ The `move` keyword tells rust it can move the `state` signal into the closure. Since the closure owns the signal state, it can read it even after the function returns
onclick: move |_| {
println!("You clicked the button! The state is: {state}");
},
"Click me"
}
}
}use of moved value: `your_value` value used here after move
Data in rust has a single owner. If you run into this error, you have likely tried to move data that isn’t Copy into two different closures. You can fix this issue by making your data Copy or calling clone on it before you move it into the closure.
Broken component:
// `MyComponent` accepts a string which cannot be copied implicitly
#[component]
fn MyComponent(string: String) -> Element {
rsx! {
button {
// ❌ We are moving the string into the onclick handler which means we can't access it elsewhere
onclick: move |_| {
println!("{string}");
},
"Print hello world"
}
button {
// ❌ Since we already moved the string, we can't move it into the onclick handler again. This will cause a compiler error
onclick: move |_| {
println!("{string}");
},
"Print hello world again"
}
}
}You can fix this issue by either:
- Making your data
CopywithReadSignal:
// `MyComponent` accepts `ReadSignal<String>` which implements `Copy`
#[component]
fn MyComponent(string: ReadSignal<String>) -> Element {
rsx! {
button {
// ✅ Because the `string` signal is `Copy`, we can copy it into the closure while still having access to it elsewhere
onclick: move |_| println!("{}", string),
"Print hello world"
}
button {
// ✅ Since `string` is `Copy`, we can move it into the onclick handler again
onclick: move |_| println!("{}", string),
"Print hello world again"
}
}
}- Calling
cloneon your data before you move it into the closure:
// `MyComponent` accepts a string which doesn't implement `Copy`
#[component]
fn MyComponent(string: String) -> Element {
rsx! {
button {
// ✅ The string only has one owner. We could move it into this closure, but since we want to use the string in other closures later, we will clone it instead
onclick: {
// Clone the string in a new block
let string = string.clone();
// Then move the cloned string into the closure
move |_| println!("{}", string)
},
"Print hello world"
}
button {
// ✅ We don't use the string after this closure, so we can just move it into the closure directly
onclick: move |_| println!("{}", string),
"Print hello world again"
}
}
}Sourcefn onkeydown<__Marker>(
self,
event_handler: impl EventHandlerValue<KeyboardData, __Marker>,
) -> <Self as AttributeBuilderTarget>::Output
fn onkeydown<__Marker>( self, event_handler: impl EventHandlerValue<KeyboardData, __Marker>, ) -> <Self as AttributeBuilderTarget>::Output
onkeydown
General Event Handler Information
§Event Handlers
Event Handlers let you react to user input in your application. In Dioxus, event handlers accept a closure that is called when the event occurs:
use dioxus::prelude::*;
fn App() -> Element {
rsx! {
button {
// The `onclick` event accepts a closure with the signature `fn(Event)`
onclick: |event_data| println!("clicked! I got the event data: {event_data:?}"),
"Click me"
}
}
}§Event Lifetimes
Events take a closure with the 'static lifetime. This means that the closure can only access data that either exists for the entire lifetime of the application, or data that you move into the closure.
State in dioxus is copy which makes it very easy to move into 'static closures like event handlers:
let mut count = use_signal(|| 0);
rsx! {
button {
// Since we added the `move` keyword, the closure will move the `count` signal into the closure
onclick: move |_| {
// This will panic because the `count` signal is not in scope
count.set(count() + 1);
},
"Click me"
}
};If you need to access data that is not Copy, you may need to clone the data before you move it into the closure:
// String is not `Copy`
let string = "hello world".to_string();
rsx! {
button {
// The string only has one owner. We could move it into this closure, but since we want to use the string in other closures later, we will clone it instead
onclick: {
// Clone the string in a new block
let string = string.clone();
// Then move the cloned string into the closure
move |_| println!("{}", string)
},
"Print hello world"
}
button {
// We don't use the string after this closure, so we can just move it into the closure directly
onclick: move |_| println!("{}", string),
"Print hello world again"
}
};§Async Event Handlers
In addition to closures that return nothing, you can also use async closures to handle events. If you return an async block from an event handler, dioxus will automatically spawn it:
use dioxus::prelude::*;
fn App() -> Element {
rsx! {
button {
// The `onclick` event can also accept a closure that returns an async block
onclick: move |_| async move {
tokio::time::sleep(std::time::Duration::from_secs(1)).await;
println!("You clicked the button one second ago!");
},
"Click me"
}
}
}§Compiler errors you may run into while using event handlers
function requires argument type to outlive `'static`
Event handler in Dioxus need only access data that can last for the entire lifetime of the application. That generally means data that is moved into the closure. If you get this error, you may have forgotten to add move to your closure.
Broken component:
// We return an Element which can last as long as the component is on the screen
fn App() -> Element {
// Signals are `Copy` which makes them very easy to move into `'static` closures like event handlers
let state = use_signal(|| "hello world".to_string());
rsx! {
button {
// ❌ Without `move`, rust will try to borrow the `state` signal which fails because the state signal is dropped at the end of the function
onclick: |_| {
println!("You clicked the button! The state is: {state}");
},
"Click me"
}
}
// The state signal is dropped here, but the event handler still needs to access it
}Fixed component:
fn App() -> Element {
let state = use_signal(|| "hello world".to_string());
rsx! {
button {
// ✅ The `move` keyword tells rust it can move the `state` signal into the closure. Since the closure owns the signal state, it can read it even after the function returns
onclick: move |_| {
println!("You clicked the button! The state is: {state}");
},
"Click me"
}
}
}use of moved value: `your_value` value used here after move
Data in rust has a single owner. If you run into this error, you have likely tried to move data that isn’t Copy into two different closures. You can fix this issue by making your data Copy or calling clone on it before you move it into the closure.
Broken component:
// `MyComponent` accepts a string which cannot be copied implicitly
#[component]
fn MyComponent(string: String) -> Element {
rsx! {
button {
// ❌ We are moving the string into the onclick handler which means we can't access it elsewhere
onclick: move |_| {
println!("{string}");
},
"Print hello world"
}
button {
// ❌ Since we already moved the string, we can't move it into the onclick handler again. This will cause a compiler error
onclick: move |_| {
println!("{string}");
},
"Print hello world again"
}
}
}You can fix this issue by either:
- Making your data
CopywithReadSignal:
// `MyComponent` accepts `ReadSignal<String>` which implements `Copy`
#[component]
fn MyComponent(string: ReadSignal<String>) -> Element {
rsx! {
button {
// ✅ Because the `string` signal is `Copy`, we can copy it into the closure while still having access to it elsewhere
onclick: move |_| println!("{}", string),
"Print hello world"
}
button {
// ✅ Since `string` is `Copy`, we can move it into the onclick handler again
onclick: move |_| println!("{}", string),
"Print hello world again"
}
}
}- Calling
cloneon your data before you move it into the closure:
// `MyComponent` accepts a string which doesn't implement `Copy`
#[component]
fn MyComponent(string: String) -> Element {
rsx! {
button {
// ✅ The string only has one owner. We could move it into this closure, but since we want to use the string in other closures later, we will clone it instead
onclick: {
// Clone the string in a new block
let string = string.clone();
// Then move the cloned string into the closure
move |_| println!("{}", string)
},
"Print hello world"
}
button {
// ✅ We don't use the string after this closure, so we can just move it into the closure directly
onclick: move |_| println!("{}", string),
"Print hello world again"
}
}
}Sourcefn onkeypress<__Marker>(
self,
event_handler: impl EventHandlerValue<KeyboardData, __Marker>,
) -> <Self as AttributeBuilderTarget>::Output
fn onkeypress<__Marker>( self, event_handler: impl EventHandlerValue<KeyboardData, __Marker>, ) -> <Self as AttributeBuilderTarget>::Output
onkeypress
General Event Handler Information
§Event Handlers
Event Handlers let you react to user input in your application. In Dioxus, event handlers accept a closure that is called when the event occurs:
use dioxus::prelude::*;
fn App() -> Element {
rsx! {
button {
// The `onclick` event accepts a closure with the signature `fn(Event)`
onclick: |event_data| println!("clicked! I got the event data: {event_data:?}"),
"Click me"
}
}
}§Event Lifetimes
Events take a closure with the 'static lifetime. This means that the closure can only access data that either exists for the entire lifetime of the application, or data that you move into the closure.
State in dioxus is copy which makes it very easy to move into 'static closures like event handlers:
let mut count = use_signal(|| 0);
rsx! {
button {
// Since we added the `move` keyword, the closure will move the `count` signal into the closure
onclick: move |_| {
// This will panic because the `count` signal is not in scope
count.set(count() + 1);
},
"Click me"
}
};If you need to access data that is not Copy, you may need to clone the data before you move it into the closure:
// String is not `Copy`
let string = "hello world".to_string();
rsx! {
button {
// The string only has one owner. We could move it into this closure, but since we want to use the string in other closures later, we will clone it instead
onclick: {
// Clone the string in a new block
let string = string.clone();
// Then move the cloned string into the closure
move |_| println!("{}", string)
},
"Print hello world"
}
button {
// We don't use the string after this closure, so we can just move it into the closure directly
onclick: move |_| println!("{}", string),
"Print hello world again"
}
};§Async Event Handlers
In addition to closures that return nothing, you can also use async closures to handle events. If you return an async block from an event handler, dioxus will automatically spawn it:
use dioxus::prelude::*;
fn App() -> Element {
rsx! {
button {
// The `onclick` event can also accept a closure that returns an async block
onclick: move |_| async move {
tokio::time::sleep(std::time::Duration::from_secs(1)).await;
println!("You clicked the button one second ago!");
},
"Click me"
}
}
}§Compiler errors you may run into while using event handlers
function requires argument type to outlive `'static`
Event handler in Dioxus need only access data that can last for the entire lifetime of the application. That generally means data that is moved into the closure. If you get this error, you may have forgotten to add move to your closure.
Broken component:
// We return an Element which can last as long as the component is on the screen
fn App() -> Element {
// Signals are `Copy` which makes them very easy to move into `'static` closures like event handlers
let state = use_signal(|| "hello world".to_string());
rsx! {
button {
// ❌ Without `move`, rust will try to borrow the `state` signal which fails because the state signal is dropped at the end of the function
onclick: |_| {
println!("You clicked the button! The state is: {state}");
},
"Click me"
}
}
// The state signal is dropped here, but the event handler still needs to access it
}Fixed component:
fn App() -> Element {
let state = use_signal(|| "hello world".to_string());
rsx! {
button {
// ✅ The `move` keyword tells rust it can move the `state` signal into the closure. Since the closure owns the signal state, it can read it even after the function returns
onclick: move |_| {
println!("You clicked the button! The state is: {state}");
},
"Click me"
}
}
}use of moved value: `your_value` value used here after move
Data in rust has a single owner. If you run into this error, you have likely tried to move data that isn’t Copy into two different closures. You can fix this issue by making your data Copy or calling clone on it before you move it into the closure.
Broken component:
// `MyComponent` accepts a string which cannot be copied implicitly
#[component]
fn MyComponent(string: String) -> Element {
rsx! {
button {
// ❌ We are moving the string into the onclick handler which means we can't access it elsewhere
onclick: move |_| {
println!("{string}");
},
"Print hello world"
}
button {
// ❌ Since we already moved the string, we can't move it into the onclick handler again. This will cause a compiler error
onclick: move |_| {
println!("{string}");
},
"Print hello world again"
}
}
}You can fix this issue by either:
- Making your data
CopywithReadSignal:
// `MyComponent` accepts `ReadSignal<String>` which implements `Copy`
#[component]
fn MyComponent(string: ReadSignal<String>) -> Element {
rsx! {
button {
// ✅ Because the `string` signal is `Copy`, we can copy it into the closure while still having access to it elsewhere
onclick: move |_| println!("{}", string),
"Print hello world"
}
button {
// ✅ Since `string` is `Copy`, we can move it into the onclick handler again
onclick: move |_| println!("{}", string),
"Print hello world again"
}
}
}- Calling
cloneon your data before you move it into the closure:
// `MyComponent` accepts a string which doesn't implement `Copy`
#[component]
fn MyComponent(string: String) -> Element {
rsx! {
button {
// ✅ The string only has one owner. We could move it into this closure, but since we want to use the string in other closures later, we will clone it instead
onclick: {
// Clone the string in a new block
let string = string.clone();
// Then move the cloned string into the closure
move |_| println!("{}", string)
},
"Print hello world"
}
button {
// ✅ We don't use the string after this closure, so we can just move it into the closure directly
onclick: move |_| println!("{}", string),
"Print hello world again"
}
}
}Sourcefn onkeyup<__Marker>(
self,
event_handler: impl EventHandlerValue<KeyboardData, __Marker>,
) -> <Self as AttributeBuilderTarget>::Output
fn onkeyup<__Marker>( self, event_handler: impl EventHandlerValue<KeyboardData, __Marker>, ) -> <Self as AttributeBuilderTarget>::Output
onkeyup
General Event Handler Information
§Event Handlers
Event Handlers let you react to user input in your application. In Dioxus, event handlers accept a closure that is called when the event occurs:
use dioxus::prelude::*;
fn App() -> Element {
rsx! {
button {
// The `onclick` event accepts a closure with the signature `fn(Event)`
onclick: |event_data| println!("clicked! I got the event data: {event_data:?}"),
"Click me"
}
}
}§Event Lifetimes
Events take a closure with the 'static lifetime. This means that the closure can only access data that either exists for the entire lifetime of the application, or data that you move into the closure.
State in dioxus is copy which makes it very easy to move into 'static closures like event handlers:
let mut count = use_signal(|| 0);
rsx! {
button {
// Since we added the `move` keyword, the closure will move the `count` signal into the closure
onclick: move |_| {
// This will panic because the `count` signal is not in scope
count.set(count() + 1);
},
"Click me"
}
};If you need to access data that is not Copy, you may need to clone the data before you move it into the closure:
// String is not `Copy`
let string = "hello world".to_string();
rsx! {
button {
// The string only has one owner. We could move it into this closure, but since we want to use the string in other closures later, we will clone it instead
onclick: {
// Clone the string in a new block
let string = string.clone();
// Then move the cloned string into the closure
move |_| println!("{}", string)
},
"Print hello world"
}
button {
// We don't use the string after this closure, so we can just move it into the closure directly
onclick: move |_| println!("{}", string),
"Print hello world again"
}
};§Async Event Handlers
In addition to closures that return nothing, you can also use async closures to handle events. If you return an async block from an event handler, dioxus will automatically spawn it:
use dioxus::prelude::*;
fn App() -> Element {
rsx! {
button {
// The `onclick` event can also accept a closure that returns an async block
onclick: move |_| async move {
tokio::time::sleep(std::time::Duration::from_secs(1)).await;
println!("You clicked the button one second ago!");
},
"Click me"
}
}
}§Compiler errors you may run into while using event handlers
function requires argument type to outlive `'static`
Event handler in Dioxus need only access data that can last for the entire lifetime of the application. That generally means data that is moved into the closure. If you get this error, you may have forgotten to add move to your closure.
Broken component:
// We return an Element which can last as long as the component is on the screen
fn App() -> Element {
// Signals are `Copy` which makes them very easy to move into `'static` closures like event handlers
let state = use_signal(|| "hello world".to_string());
rsx! {
button {
// ❌ Without `move`, rust will try to borrow the `state` signal which fails because the state signal is dropped at the end of the function
onclick: |_| {
println!("You clicked the button! The state is: {state}");
},
"Click me"
}
}
// The state signal is dropped here, but the event handler still needs to access it
}Fixed component:
fn App() -> Element {
let state = use_signal(|| "hello world".to_string());
rsx! {
button {
// ✅ The `move` keyword tells rust it can move the `state` signal into the closure. Since the closure owns the signal state, it can read it even after the function returns
onclick: move |_| {
println!("You clicked the button! The state is: {state}");
},
"Click me"
}
}
}use of moved value: `your_value` value used here after move
Data in rust has a single owner. If you run into this error, you have likely tried to move data that isn’t Copy into two different closures. You can fix this issue by making your data Copy or calling clone on it before you move it into the closure.
Broken component:
// `MyComponent` accepts a string which cannot be copied implicitly
#[component]
fn MyComponent(string: String) -> Element {
rsx! {
button {
// ❌ We are moving the string into the onclick handler which means we can't access it elsewhere
onclick: move |_| {
println!("{string}");
},
"Print hello world"
}
button {
// ❌ Since we already moved the string, we can't move it into the onclick handler again. This will cause a compiler error
onclick: move |_| {
println!("{string}");
},
"Print hello world again"
}
}
}You can fix this issue by either:
- Making your data
CopywithReadSignal:
// `MyComponent` accepts `ReadSignal<String>` which implements `Copy`
#[component]
fn MyComponent(string: ReadSignal<String>) -> Element {
rsx! {
button {
// ✅ Because the `string` signal is `Copy`, we can copy it into the closure while still having access to it elsewhere
onclick: move |_| println!("{}", string),
"Print hello world"
}
button {
// ✅ Since `string` is `Copy`, we can move it into the onclick handler again
onclick: move |_| println!("{}", string),
"Print hello world again"
}
}
}- Calling
cloneon your data before you move it into the closure:
// `MyComponent` accepts a string which doesn't implement `Copy`
#[component]
fn MyComponent(string: String) -> Element {
rsx! {
button {
// ✅ The string only has one owner. We could move it into this closure, but since we want to use the string in other closures later, we will clone it instead
onclick: {
// Clone the string in a new block
let string = string.clone();
// Then move the cloned string into the closure
move |_| println!("{}", string)
},
"Print hello world"
}
button {
// ✅ We don't use the string after this closure, so we can just move it into the closure directly
onclick: move |_| println!("{}", string),
"Print hello world again"
}
}
}Sourcefn onabort<__Marker>(
self,
event_handler: impl EventHandlerValue<MediaData, __Marker>,
) -> <Self as AttributeBuilderTarget>::Output
fn onabort<__Marker>( self, event_handler: impl EventHandlerValue<MediaData, __Marker>, ) -> <Self as AttributeBuilderTarget>::Output
onabort
General Event Handler Information
§Event Handlers
Event Handlers let you react to user input in your application. In Dioxus, event handlers accept a closure that is called when the event occurs:
use dioxus::prelude::*;
fn App() -> Element {
rsx! {
button {
// The `onclick` event accepts a closure with the signature `fn(Event)`
onclick: |event_data| println!("clicked! I got the event data: {event_data:?}"),
"Click me"
}
}
}§Event Lifetimes
Events take a closure with the 'static lifetime. This means that the closure can only access data that either exists for the entire lifetime of the application, or data that you move into the closure.
State in dioxus is copy which makes it very easy to move into 'static closures like event handlers:
let mut count = use_signal(|| 0);
rsx! {
button {
// Since we added the `move` keyword, the closure will move the `count` signal into the closure
onclick: move |_| {
// This will panic because the `count` signal is not in scope
count.set(count() + 1);
},
"Click me"
}
};If you need to access data that is not Copy, you may need to clone the data before you move it into the closure:
// String is not `Copy`
let string = "hello world".to_string();
rsx! {
button {
// The string only has one owner. We could move it into this closure, but since we want to use the string in other closures later, we will clone it instead
onclick: {
// Clone the string in a new block
let string = string.clone();
// Then move the cloned string into the closure
move |_| println!("{}", string)
},
"Print hello world"
}
button {
// We don't use the string after this closure, so we can just move it into the closure directly
onclick: move |_| println!("{}", string),
"Print hello world again"
}
};§Async Event Handlers
In addition to closures that return nothing, you can also use async closures to handle events. If you return an async block from an event handler, dioxus will automatically spawn it:
use dioxus::prelude::*;
fn App() -> Element {
rsx! {
button {
// The `onclick` event can also accept a closure that returns an async block
onclick: move |_| async move {
tokio::time::sleep(std::time::Duration::from_secs(1)).await;
println!("You clicked the button one second ago!");
},
"Click me"
}
}
}§Compiler errors you may run into while using event handlers
function requires argument type to outlive `'static`
Event handler in Dioxus need only access data that can last for the entire lifetime of the application. That generally means data that is moved into the closure. If you get this error, you may have forgotten to add move to your closure.
Broken component:
// We return an Element which can last as long as the component is on the screen
fn App() -> Element {
// Signals are `Copy` which makes them very easy to move into `'static` closures like event handlers
let state = use_signal(|| "hello world".to_string());
rsx! {
button {
// ❌ Without `move`, rust will try to borrow the `state` signal which fails because the state signal is dropped at the end of the function
onclick: |_| {
println!("You clicked the button! The state is: {state}");
},
"Click me"
}
}
// The state signal is dropped here, but the event handler still needs to access it
}Fixed component:
fn App() -> Element {
let state = use_signal(|| "hello world".to_string());
rsx! {
button {
// ✅ The `move` keyword tells rust it can move the `state` signal into the closure. Since the closure owns the signal state, it can read it even after the function returns
onclick: move |_| {
println!("You clicked the button! The state is: {state}");
},
"Click me"
}
}
}use of moved value: `your_value` value used here after move
Data in rust has a single owner. If you run into this error, you have likely tried to move data that isn’t Copy into two different closures. You can fix this issue by making your data Copy or calling clone on it before you move it into the closure.
Broken component:
// `MyComponent` accepts a string which cannot be copied implicitly
#[component]
fn MyComponent(string: String) -> Element {
rsx! {
button {
// ❌ We are moving the string into the onclick handler which means we can't access it elsewhere
onclick: move |_| {
println!("{string}");
},
"Print hello world"
}
button {
// ❌ Since we already moved the string, we can't move it into the onclick handler again. This will cause a compiler error
onclick: move |_| {
println!("{string}");
},
"Print hello world again"
}
}
}You can fix this issue by either:
- Making your data
CopywithReadSignal:
// `MyComponent` accepts `ReadSignal<String>` which implements `Copy`
#[component]
fn MyComponent(string: ReadSignal<String>) -> Element {
rsx! {
button {
// ✅ Because the `string` signal is `Copy`, we can copy it into the closure while still having access to it elsewhere
onclick: move |_| println!("{}", string),
"Print hello world"
}
button {
// ✅ Since `string` is `Copy`, we can move it into the onclick handler again
onclick: move |_| println!("{}", string),
"Print hello world again"
}
}
}- Calling
cloneon your data before you move it into the closure:
// `MyComponent` accepts a string which doesn't implement `Copy`
#[component]
fn MyComponent(string: String) -> Element {
rsx! {
button {
// ✅ The string only has one owner. We could move it into this closure, but since we want to use the string in other closures later, we will clone it instead
onclick: {
// Clone the string in a new block
let string = string.clone();
// Then move the cloned string into the closure
move |_| println!("{}", string)
},
"Print hello world"
}
button {
// ✅ We don't use the string after this closure, so we can just move it into the closure directly
onclick: move |_| println!("{}", string),
"Print hello world again"
}
}
}Sourcefn oncanplay<__Marker>(
self,
event_handler: impl EventHandlerValue<MediaData, __Marker>,
) -> <Self as AttributeBuilderTarget>::Output
fn oncanplay<__Marker>( self, event_handler: impl EventHandlerValue<MediaData, __Marker>, ) -> <Self as AttributeBuilderTarget>::Output
oncanplay
General Event Handler Information
§Event Handlers
Event Handlers let you react to user input in your application. In Dioxus, event handlers accept a closure that is called when the event occurs:
use dioxus::prelude::*;
fn App() -> Element {
rsx! {
button {
// The `onclick` event accepts a closure with the signature `fn(Event)`
onclick: |event_data| println!("clicked! I got the event data: {event_data:?}"),
"Click me"
}
}
}§Event Lifetimes
Events take a closure with the 'static lifetime. This means that the closure can only access data that either exists for the entire lifetime of the application, or data that you move into the closure.
State in dioxus is copy which makes it very easy to move into 'static closures like event handlers:
let mut count = use_signal(|| 0);
rsx! {
button {
// Since we added the `move` keyword, the closure will move the `count` signal into the closure
onclick: move |_| {
// This will panic because the `count` signal is not in scope
count.set(count() + 1);
},
"Click me"
}
};If you need to access data that is not Copy, you may need to clone the data before you move it into the closure:
// String is not `Copy`
let string = "hello world".to_string();
rsx! {
button {
// The string only has one owner. We could move it into this closure, but since we want to use the string in other closures later, we will clone it instead
onclick: {
// Clone the string in a new block
let string = string.clone();
// Then move the cloned string into the closure
move |_| println!("{}", string)
},
"Print hello world"
}
button {
// We don't use the string after this closure, so we can just move it into the closure directly
onclick: move |_| println!("{}", string),
"Print hello world again"
}
};§Async Event Handlers
In addition to closures that return nothing, you can also use async closures to handle events. If you return an async block from an event handler, dioxus will automatically spawn it:
use dioxus::prelude::*;
fn App() -> Element {
rsx! {
button {
// The `onclick` event can also accept a closure that returns an async block
onclick: move |_| async move {
tokio::time::sleep(std::time::Duration::from_secs(1)).await;
println!("You clicked the button one second ago!");
},
"Click me"
}
}
}§Compiler errors you may run into while using event handlers
function requires argument type to outlive `'static`
Event handler in Dioxus need only access data that can last for the entire lifetime of the application. That generally means data that is moved into the closure. If you get this error, you may have forgotten to add move to your closure.
Broken component:
// We return an Element which can last as long as the component is on the screen
fn App() -> Element {
// Signals are `Copy` which makes them very easy to move into `'static` closures like event handlers
let state = use_signal(|| "hello world".to_string());
rsx! {
button {
// ❌ Without `move`, rust will try to borrow the `state` signal which fails because the state signal is dropped at the end of the function
onclick: |_| {
println!("You clicked the button! The state is: {state}");
},
"Click me"
}
}
// The state signal is dropped here, but the event handler still needs to access it
}Fixed component:
fn App() -> Element {
let state = use_signal(|| "hello world".to_string());
rsx! {
button {
// ✅ The `move` keyword tells rust it can move the `state` signal into the closure. Since the closure owns the signal state, it can read it even after the function returns
onclick: move |_| {
println!("You clicked the button! The state is: {state}");
},
"Click me"
}
}
}use of moved value: `your_value` value used here after move
Data in rust has a single owner. If you run into this error, you have likely tried to move data that isn’t Copy into two different closures. You can fix this issue by making your data Copy or calling clone on it before you move it into the closure.
Broken component:
// `MyComponent` accepts a string which cannot be copied implicitly
#[component]
fn MyComponent(string: String) -> Element {
rsx! {
button {
// ❌ We are moving the string into the onclick handler which means we can't access it elsewhere
onclick: move |_| {
println!("{string}");
},
"Print hello world"
}
button {
// ❌ Since we already moved the string, we can't move it into the onclick handler again. This will cause a compiler error
onclick: move |_| {
println!("{string}");
},
"Print hello world again"
}
}
}You can fix this issue by either:
- Making your data
CopywithReadSignal:
// `MyComponent` accepts `ReadSignal<String>` which implements `Copy`
#[component]
fn MyComponent(string: ReadSignal<String>) -> Element {
rsx! {
button {
// ✅ Because the `string` signal is `Copy`, we can copy it into the closure while still having access to it elsewhere
onclick: move |_| println!("{}", string),
"Print hello world"
}
button {
// ✅ Since `string` is `Copy`, we can move it into the onclick handler again
onclick: move |_| println!("{}", string),
"Print hello world again"
}
}
}- Calling
cloneon your data before you move it into the closure:
// `MyComponent` accepts a string which doesn't implement `Copy`
#[component]
fn MyComponent(string: String) -> Element {
rsx! {
button {
// ✅ The string only has one owner. We could move it into this closure, but since we want to use the string in other closures later, we will clone it instead
onclick: {
// Clone the string in a new block
let string = string.clone();
// Then move the cloned string into the closure
move |_| println!("{}", string)
},
"Print hello world"
}
button {
// ✅ We don't use the string after this closure, so we can just move it into the closure directly
onclick: move |_| println!("{}", string),
"Print hello world again"
}
}
}Sourcefn oncanplaythrough<__Marker>(
self,
event_handler: impl EventHandlerValue<MediaData, __Marker>,
) -> <Self as AttributeBuilderTarget>::Output
fn oncanplaythrough<__Marker>( self, event_handler: impl EventHandlerValue<MediaData, __Marker>, ) -> <Self as AttributeBuilderTarget>::Output
oncanplaythrough
General Event Handler Information
§Event Handlers
Event Handlers let you react to user input in your application. In Dioxus, event handlers accept a closure that is called when the event occurs:
use dioxus::prelude::*;
fn App() -> Element {
rsx! {
button {
// The `onclick` event accepts a closure with the signature `fn(Event)`
onclick: |event_data| println!("clicked! I got the event data: {event_data:?}"),
"Click me"
}
}
}§Event Lifetimes
Events take a closure with the 'static lifetime. This means that the closure can only access data that either exists for the entire lifetime of the application, or data that you move into the closure.
State in dioxus is copy which makes it very easy to move into 'static closures like event handlers:
let mut count = use_signal(|| 0);
rsx! {
button {
// Since we added the `move` keyword, the closure will move the `count` signal into the closure
onclick: move |_| {
// This will panic because the `count` signal is not in scope
count.set(count() + 1);
},
"Click me"
}
};If you need to access data that is not Copy, you may need to clone the data before you move it into the closure:
// String is not `Copy`
let string = "hello world".to_string();
rsx! {
button {
// The string only has one owner. We could move it into this closure, but since we want to use the string in other closures later, we will clone it instead
onclick: {
// Clone the string in a new block
let string = string.clone();
// Then move the cloned string into the closure
move |_| println!("{}", string)
},
"Print hello world"
}
button {
// We don't use the string after this closure, so we can just move it into the closure directly
onclick: move |_| println!("{}", string),
"Print hello world again"
}
};§Async Event Handlers
In addition to closures that return nothing, you can also use async closures to handle events. If you return an async block from an event handler, dioxus will automatically spawn it:
use dioxus::prelude::*;
fn App() -> Element {
rsx! {
button {
// The `onclick` event can also accept a closure that returns an async block
onclick: move |_| async move {
tokio::time::sleep(std::time::Duration::from_secs(1)).await;
println!("You clicked the button one second ago!");
},
"Click me"
}
}
}§Compiler errors you may run into while using event handlers
function requires argument type to outlive `'static`
Event handler in Dioxus need only access data that can last for the entire lifetime of the application. That generally means data that is moved into the closure. If you get this error, you may have forgotten to add move to your closure.
Broken component:
// We return an Element which can last as long as the component is on the screen
fn App() -> Element {
// Signals are `Copy` which makes them very easy to move into `'static` closures like event handlers
let state = use_signal(|| "hello world".to_string());
rsx! {
button {
// ❌ Without `move`, rust will try to borrow the `state` signal which fails because the state signal is dropped at the end of the function
onclick: |_| {
println!("You clicked the button! The state is: {state}");
},
"Click me"
}
}
// The state signal is dropped here, but the event handler still needs to access it
}Fixed component:
fn App() -> Element {
let state = use_signal(|| "hello world".to_string());
rsx! {
button {
// ✅ The `move` keyword tells rust it can move the `state` signal into the closure. Since the closure owns the signal state, it can read it even after the function returns
onclick: move |_| {
println!("You clicked the button! The state is: {state}");
},
"Click me"
}
}
}use of moved value: `your_value` value used here after move
Data in rust has a single owner. If you run into this error, you have likely tried to move data that isn’t Copy into two different closures. You can fix this issue by making your data Copy or calling clone on it before you move it into the closure.
Broken component:
// `MyComponent` accepts a string which cannot be copied implicitly
#[component]
fn MyComponent(string: String) -> Element {
rsx! {
button {
// ❌ We are moving the string into the onclick handler which means we can't access it elsewhere
onclick: move |_| {
println!("{string}");
},
"Print hello world"
}
button {
// ❌ Since we already moved the string, we can't move it into the onclick handler again. This will cause a compiler error
onclick: move |_| {
println!("{string}");
},
"Print hello world again"
}
}
}You can fix this issue by either:
- Making your data
CopywithReadSignal:
// `MyComponent` accepts `ReadSignal<String>` which implements `Copy`
#[component]
fn MyComponent(string: ReadSignal<String>) -> Element {
rsx! {
button {
// ✅ Because the `string` signal is `Copy`, we can copy it into the closure while still having access to it elsewhere
onclick: move |_| println!("{}", string),
"Print hello world"
}
button {
// ✅ Since `string` is `Copy`, we can move it into the onclick handler again
onclick: move |_| println!("{}", string),
"Print hello world again"
}
}
}- Calling
cloneon your data before you move it into the closure:
// `MyComponent` accepts a string which doesn't implement `Copy`
#[component]
fn MyComponent(string: String) -> Element {
rsx! {
button {
// ✅ The string only has one owner. We could move it into this closure, but since we want to use the string in other closures later, we will clone it instead
onclick: {
// Clone the string in a new block
let string = string.clone();
// Then move the cloned string into the closure
move |_| println!("{}", string)
},
"Print hello world"
}
button {
// ✅ We don't use the string after this closure, so we can just move it into the closure directly
onclick: move |_| println!("{}", string),
"Print hello world again"
}
}
}Sourcefn ondurationchange<__Marker>(
self,
event_handler: impl EventHandlerValue<MediaData, __Marker>,
) -> <Self as AttributeBuilderTarget>::Output
fn ondurationchange<__Marker>( self, event_handler: impl EventHandlerValue<MediaData, __Marker>, ) -> <Self as AttributeBuilderTarget>::Output
ondurationchange
General Event Handler Information
§Event Handlers
Event Handlers let you react to user input in your application. In Dioxus, event handlers accept a closure that is called when the event occurs:
use dioxus::prelude::*;
fn App() -> Element {
rsx! {
button {
// The `onclick` event accepts a closure with the signature `fn(Event)`
onclick: |event_data| println!("clicked! I got the event data: {event_data:?}"),
"Click me"
}
}
}§Event Lifetimes
Events take a closure with the 'static lifetime. This means that the closure can only access data that either exists for the entire lifetime of the application, or data that you move into the closure.
State in dioxus is copy which makes it very easy to move into 'static closures like event handlers:
let mut count = use_signal(|| 0);
rsx! {
button {
// Since we added the `move` keyword, the closure will move the `count` signal into the closure
onclick: move |_| {
// This will panic because the `count` signal is not in scope
count.set(count() + 1);
},
"Click me"
}
};If you need to access data that is not Copy, you may need to clone the data before you move it into the closure:
// String is not `Copy`
let string = "hello world".to_string();
rsx! {
button {
// The string only has one owner. We could move it into this closure, but since we want to use the string in other closures later, we will clone it instead
onclick: {
// Clone the string in a new block
let string = string.clone();
// Then move the cloned string into the closure
move |_| println!("{}", string)
},
"Print hello world"
}
button {
// We don't use the string after this closure, so we can just move it into the closure directly
onclick: move |_| println!("{}", string),
"Print hello world again"
}
};§Async Event Handlers
In addition to closures that return nothing, you can also use async closures to handle events. If you return an async block from an event handler, dioxus will automatically spawn it:
use dioxus::prelude::*;
fn App() -> Element {
rsx! {
button {
// The `onclick` event can also accept a closure that returns an async block
onclick: move |_| async move {
tokio::time::sleep(std::time::Duration::from_secs(1)).await;
println!("You clicked the button one second ago!");
},
"Click me"
}
}
}§Compiler errors you may run into while using event handlers
function requires argument type to outlive `'static`
Event handler in Dioxus need only access data that can last for the entire lifetime of the application. That generally means data that is moved into the closure. If you get this error, you may have forgotten to add move to your closure.
Broken component:
// We return an Element which can last as long as the component is on the screen
fn App() -> Element {
// Signals are `Copy` which makes them very easy to move into `'static` closures like event handlers
let state = use_signal(|| "hello world".to_string());
rsx! {
button {
// ❌ Without `move`, rust will try to borrow the `state` signal which fails because the state signal is dropped at the end of the function
onclick: |_| {
println!("You clicked the button! The state is: {state}");
},
"Click me"
}
}
// The state signal is dropped here, but the event handler still needs to access it
}Fixed component:
fn App() -> Element {
let state = use_signal(|| "hello world".to_string());
rsx! {
button {
// ✅ The `move` keyword tells rust it can move the `state` signal into the closure. Since the closure owns the signal state, it can read it even after the function returns
onclick: move |_| {
println!("You clicked the button! The state is: {state}");
},
"Click me"
}
}
}use of moved value: `your_value` value used here after move
Data in rust has a single owner. If you run into this error, you have likely tried to move data that isn’t Copy into two different closures. You can fix this issue by making your data Copy or calling clone on it before you move it into the closure.
Broken component:
// `MyComponent` accepts a string which cannot be copied implicitly
#[component]
fn MyComponent(string: String) -> Element {
rsx! {
button {
// ❌ We are moving the string into the onclick handler which means we can't access it elsewhere
onclick: move |_| {
println!("{string}");
},
"Print hello world"
}
button {
// ❌ Since we already moved the string, we can't move it into the onclick handler again. This will cause a compiler error
onclick: move |_| {
println!("{string}");
},
"Print hello world again"
}
}
}You can fix this issue by either:
- Making your data
CopywithReadSignal:
// `MyComponent` accepts `ReadSignal<String>` which implements `Copy`
#[component]
fn MyComponent(string: ReadSignal<String>) -> Element {
rsx! {
button {
// ✅ Because the `string` signal is `Copy`, we can copy it into the closure while still having access to it elsewhere
onclick: move |_| println!("{}", string),
"Print hello world"
}
button {
// ✅ Since `string` is `Copy`, we can move it into the onclick handler again
onclick: move |_| println!("{}", string),
"Print hello world again"
}
}
}- Calling
cloneon your data before you move it into the closure:
// `MyComponent` accepts a string which doesn't implement `Copy`
#[component]
fn MyComponent(string: String) -> Element {
rsx! {
button {
// ✅ The string only has one owner. We could move it into this closure, but since we want to use the string in other closures later, we will clone it instead
onclick: {
// Clone the string in a new block
let string = string.clone();
// Then move the cloned string into the closure
move |_| println!("{}", string)
},
"Print hello world"
}
button {
// ✅ We don't use the string after this closure, so we can just move it into the closure directly
onclick: move |_| println!("{}", string),
"Print hello world again"
}
}
}Sourcefn onemptied<__Marker>(
self,
event_handler: impl EventHandlerValue<MediaData, __Marker>,
) -> <Self as AttributeBuilderTarget>::Output
fn onemptied<__Marker>( self, event_handler: impl EventHandlerValue<MediaData, __Marker>, ) -> <Self as AttributeBuilderTarget>::Output
onemptied
General Event Handler Information
§Event Handlers
Event Handlers let you react to user input in your application. In Dioxus, event handlers accept a closure that is called when the event occurs:
use dioxus::prelude::*;
fn App() -> Element {
rsx! {
button {
// The `onclick` event accepts a closure with the signature `fn(Event)`
onclick: |event_data| println!("clicked! I got the event data: {event_data:?}"),
"Click me"
}
}
}§Event Lifetimes
Events take a closure with the 'static lifetime. This means that the closure can only access data that either exists for the entire lifetime of the application, or data that you move into the closure.
State in dioxus is copy which makes it very easy to move into 'static closures like event handlers:
let mut count = use_signal(|| 0);
rsx! {
button {
// Since we added the `move` keyword, the closure will move the `count` signal into the closure
onclick: move |_| {
// This will panic because the `count` signal is not in scope
count.set(count() + 1);
},
"Click me"
}
};If you need to access data that is not Copy, you may need to clone the data before you move it into the closure:
// String is not `Copy`
let string = "hello world".to_string();
rsx! {
button {
// The string only has one owner. We could move it into this closure, but since we want to use the string in other closures later, we will clone it instead
onclick: {
// Clone the string in a new block
let string = string.clone();
// Then move the cloned string into the closure
move |_| println!("{}", string)
},
"Print hello world"
}
button {
// We don't use the string after this closure, so we can just move it into the closure directly
onclick: move |_| println!("{}", string),
"Print hello world again"
}
};§Async Event Handlers
In addition to closures that return nothing, you can also use async closures to handle events. If you return an async block from an event handler, dioxus will automatically spawn it:
use dioxus::prelude::*;
fn App() -> Element {
rsx! {
button {
// The `onclick` event can also accept a closure that returns an async block
onclick: move |_| async move {
tokio::time::sleep(std::time::Duration::from_secs(1)).await;
println!("You clicked the button one second ago!");
},
"Click me"
}
}
}§Compiler errors you may run into while using event handlers
function requires argument type to outlive `'static`
Event handler in Dioxus need only access data that can last for the entire lifetime of the application. That generally means data that is moved into the closure. If you get this error, you may have forgotten to add move to your closure.
Broken component:
// We return an Element which can last as long as the component is on the screen
fn App() -> Element {
// Signals are `Copy` which makes them very easy to move into `'static` closures like event handlers
let state = use_signal(|| "hello world".to_string());
rsx! {
button {
// ❌ Without `move`, rust will try to borrow the `state` signal which fails because the state signal is dropped at the end of the function
onclick: |_| {
println!("You clicked the button! The state is: {state}");
},
"Click me"
}
}
// The state signal is dropped here, but the event handler still needs to access it
}Fixed component:
fn App() -> Element {
let state = use_signal(|| "hello world".to_string());
rsx! {
button {
// ✅ The `move` keyword tells rust it can move the `state` signal into the closure. Since the closure owns the signal state, it can read it even after the function returns
onclick: move |_| {
println!("You clicked the button! The state is: {state}");
},
"Click me"
}
}
}use of moved value: `your_value` value used here after move
Data in rust has a single owner. If you run into this error, you have likely tried to move data that isn’t Copy into two different closures. You can fix this issue by making your data Copy or calling clone on it before you move it into the closure.
Broken component:
// `MyComponent` accepts a string which cannot be copied implicitly
#[component]
fn MyComponent(string: String) -> Element {
rsx! {
button {
// ❌ We are moving the string into the onclick handler which means we can't access it elsewhere
onclick: move |_| {
println!("{string}");
},
"Print hello world"
}
button {
// ❌ Since we already moved the string, we can't move it into the onclick handler again. This will cause a compiler error
onclick: move |_| {
println!("{string}");
},
"Print hello world again"
}
}
}You can fix this issue by either:
- Making your data
CopywithReadSignal:
// `MyComponent` accepts `ReadSignal<String>` which implements `Copy`
#[component]
fn MyComponent(string: ReadSignal<String>) -> Element {
rsx! {
button {
// ✅ Because the `string` signal is `Copy`, we can copy it into the closure while still having access to it elsewhere
onclick: move |_| println!("{}", string),
"Print hello world"
}
button {
// ✅ Since `string` is `Copy`, we can move it into the onclick handler again
onclick: move |_| println!("{}", string),
"Print hello world again"
}
}
}- Calling
cloneon your data before you move it into the closure:
// `MyComponent` accepts a string which doesn't implement `Copy`
#[component]
fn MyComponent(string: String) -> Element {
rsx! {
button {
// ✅ The string only has one owner. We could move it into this closure, but since we want to use the string in other closures later, we will clone it instead
onclick: {
// Clone the string in a new block
let string = string.clone();
// Then move the cloned string into the closure
move |_| println!("{}", string)
},
"Print hello world"
}
button {
// ✅ We don't use the string after this closure, so we can just move it into the closure directly
onclick: move |_| println!("{}", string),
"Print hello world again"
}
}
}Sourcefn onencrypted<__Marker>(
self,
event_handler: impl EventHandlerValue<MediaData, __Marker>,
) -> <Self as AttributeBuilderTarget>::Output
fn onencrypted<__Marker>( self, event_handler: impl EventHandlerValue<MediaData, __Marker>, ) -> <Self as AttributeBuilderTarget>::Output
onencrypted
General Event Handler Information
§Event Handlers
Event Handlers let you react to user input in your application. In Dioxus, event handlers accept a closure that is called when the event occurs:
use dioxus::prelude::*;
fn App() -> Element {
rsx! {
button {
// The `onclick` event accepts a closure with the signature `fn(Event)`
onclick: |event_data| println!("clicked! I got the event data: {event_data:?}"),
"Click me"
}
}
}§Event Lifetimes
Events take a closure with the 'static lifetime. This means that the closure can only access data that either exists for the entire lifetime of the application, or data that you move into the closure.
State in dioxus is copy which makes it very easy to move into 'static closures like event handlers:
let mut count = use_signal(|| 0);
rsx! {
button {
// Since we added the `move` keyword, the closure will move the `count` signal into the closure
onclick: move |_| {
// This will panic because the `count` signal is not in scope
count.set(count() + 1);
},
"Click me"
}
};If you need to access data that is not Copy, you may need to clone the data before you move it into the closure:
// String is not `Copy`
let string = "hello world".to_string();
rsx! {
button {
// The string only has one owner. We could move it into this closure, but since we want to use the string in other closures later, we will clone it instead
onclick: {
// Clone the string in a new block
let string = string.clone();
// Then move the cloned string into the closure
move |_| println!("{}", string)
},
"Print hello world"
}
button {
// We don't use the string after this closure, so we can just move it into the closure directly
onclick: move |_| println!("{}", string),
"Print hello world again"
}
};§Async Event Handlers
In addition to closures that return nothing, you can also use async closures to handle events. If you return an async block from an event handler, dioxus will automatically spawn it:
use dioxus::prelude::*;
fn App() -> Element {
rsx! {
button {
// The `onclick` event can also accept a closure that returns an async block
onclick: move |_| async move {
tokio::time::sleep(std::time::Duration::from_secs(1)).await;
println!("You clicked the button one second ago!");
},
"Click me"
}
}
}§Compiler errors you may run into while using event handlers
function requires argument type to outlive `'static`
Event handler in Dioxus need only access data that can last for the entire lifetime of the application. That generally means data that is moved into the closure. If you get this error, you may have forgotten to add move to your closure.
Broken component:
// We return an Element which can last as long as the component is on the screen
fn App() -> Element {
// Signals are `Copy` which makes them very easy to move into `'static` closures like event handlers
let state = use_signal(|| "hello world".to_string());
rsx! {
button {
// ❌ Without `move`, rust will try to borrow the `state` signal which fails because the state signal is dropped at the end of the function
onclick: |_| {
println!("You clicked the button! The state is: {state}");
},
"Click me"
}
}
// The state signal is dropped here, but the event handler still needs to access it
}Fixed component:
fn App() -> Element {
let state = use_signal(|| "hello world".to_string());
rsx! {
button {
// ✅ The `move` keyword tells rust it can move the `state` signal into the closure. Since the closure owns the signal state, it can read it even after the function returns
onclick: move |_| {
println!("You clicked the button! The state is: {state}");
},
"Click me"
}
}
}use of moved value: `your_value` value used here after move
Data in rust has a single owner. If you run into this error, you have likely tried to move data that isn’t Copy into two different closures. You can fix this issue by making your data Copy or calling clone on it before you move it into the closure.
Broken component:
// `MyComponent` accepts a string which cannot be copied implicitly
#[component]
fn MyComponent(string: String) -> Element {
rsx! {
button {
// ❌ We are moving the string into the onclick handler which means we can't access it elsewhere
onclick: move |_| {
println!("{string}");
},
"Print hello world"
}
button {
// ❌ Since we already moved the string, we can't move it into the onclick handler again. This will cause a compiler error
onclick: move |_| {
println!("{string}");
},
"Print hello world again"
}
}
}You can fix this issue by either:
- Making your data
CopywithReadSignal:
// `MyComponent` accepts `ReadSignal<String>` which implements `Copy`
#[component]
fn MyComponent(string: ReadSignal<String>) -> Element {
rsx! {
button {
// ✅ Because the `string` signal is `Copy`, we can copy it into the closure while still having access to it elsewhere
onclick: move |_| println!("{}", string),
"Print hello world"
}
button {
// ✅ Since `string` is `Copy`, we can move it into the onclick handler again
onclick: move |_| println!("{}", string),
"Print hello world again"
}
}
}- Calling
cloneon your data before you move it into the closure:
// `MyComponent` accepts a string which doesn't implement `Copy`
#[component]
fn MyComponent(string: String) -> Element {
rsx! {
button {
// ✅ The string only has one owner. We could move it into this closure, but since we want to use the string in other closures later, we will clone it instead
onclick: {
// Clone the string in a new block
let string = string.clone();
// Then move the cloned string into the closure
move |_| println!("{}", string)
},
"Print hello world"
}
button {
// ✅ We don't use the string after this closure, so we can just move it into the closure directly
onclick: move |_| println!("{}", string),
"Print hello world again"
}
}
}Sourcefn onended<__Marker>(
self,
event_handler: impl EventHandlerValue<MediaData, __Marker>,
) -> <Self as AttributeBuilderTarget>::Output
fn onended<__Marker>( self, event_handler: impl EventHandlerValue<MediaData, __Marker>, ) -> <Self as AttributeBuilderTarget>::Output
onended
General Event Handler Information
§Event Handlers
Event Handlers let you react to user input in your application. In Dioxus, event handlers accept a closure that is called when the event occurs:
use dioxus::prelude::*;
fn App() -> Element {
rsx! {
button {
// The `onclick` event accepts a closure with the signature `fn(Event)`
onclick: |event_data| println!("clicked! I got the event data: {event_data:?}"),
"Click me"
}
}
}§Event Lifetimes
Events take a closure with the 'static lifetime. This means that the closure can only access data that either exists for the entire lifetime of the application, or data that you move into the closure.
State in dioxus is copy which makes it very easy to move into 'static closures like event handlers:
let mut count = use_signal(|| 0);
rsx! {
button {
// Since we added the `move` keyword, the closure will move the `count` signal into the closure
onclick: move |_| {
// This will panic because the `count` signal is not in scope
count.set(count() + 1);
},
"Click me"
}
};If you need to access data that is not Copy, you may need to clone the data before you move it into the closure:
// String is not `Copy`
let string = "hello world".to_string();
rsx! {
button {
// The string only has one owner. We could move it into this closure, but since we want to use the string in other closures later, we will clone it instead
onclick: {
// Clone the string in a new block
let string = string.clone();
// Then move the cloned string into the closure
move |_| println!("{}", string)
},
"Print hello world"
}
button {
// We don't use the string after this closure, so we can just move it into the closure directly
onclick: move |_| println!("{}", string),
"Print hello world again"
}
};§Async Event Handlers
In addition to closures that return nothing, you can also use async closures to handle events. If you return an async block from an event handler, dioxus will automatically spawn it:
use dioxus::prelude::*;
fn App() -> Element {
rsx! {
button {
// The `onclick` event can also accept a closure that returns an async block
onclick: move |_| async move {
tokio::time::sleep(std::time::Duration::from_secs(1)).await;
println!("You clicked the button one second ago!");
},
"Click me"
}
}
}§Compiler errors you may run into while using event handlers
function requires argument type to outlive `'static`
Event handler in Dioxus need only access data that can last for the entire lifetime of the application. That generally means data that is moved into the closure. If you get this error, you may have forgotten to add move to your closure.
Broken component:
// We return an Element which can last as long as the component is on the screen
fn App() -> Element {
// Signals are `Copy` which makes them very easy to move into `'static` closures like event handlers
let state = use_signal(|| "hello world".to_string());
rsx! {
button {
// ❌ Without `move`, rust will try to borrow the `state` signal which fails because the state signal is dropped at the end of the function
onclick: |_| {
println!("You clicked the button! The state is: {state}");
},
"Click me"
}
}
// The state signal is dropped here, but the event handler still needs to access it
}Fixed component:
fn App() -> Element {
let state = use_signal(|| "hello world".to_string());
rsx! {
button {
// ✅ The `move` keyword tells rust it can move the `state` signal into the closure. Since the closure owns the signal state, it can read it even after the function returns
onclick: move |_| {
println!("You clicked the button! The state is: {state}");
},
"Click me"
}
}
}use of moved value: `your_value` value used here after move
Data in rust has a single owner. If you run into this error, you have likely tried to move data that isn’t Copy into two different closures. You can fix this issue by making your data Copy or calling clone on it before you move it into the closure.
Broken component:
// `MyComponent` accepts a string which cannot be copied implicitly
#[component]
fn MyComponent(string: String) -> Element {
rsx! {
button {
// ❌ We are moving the string into the onclick handler which means we can't access it elsewhere
onclick: move |_| {
println!("{string}");
},
"Print hello world"
}
button {
// ❌ Since we already moved the string, we can't move it into the onclick handler again. This will cause a compiler error
onclick: move |_| {
println!("{string}");
},
"Print hello world again"
}
}
}You can fix this issue by either:
- Making your data
CopywithReadSignal:
// `MyComponent` accepts `ReadSignal<String>` which implements `Copy`
#[component]
fn MyComponent(string: ReadSignal<String>) -> Element {
rsx! {
button {
// ✅ Because the `string` signal is `Copy`, we can copy it into the closure while still having access to it elsewhere
onclick: move |_| println!("{}", string),
"Print hello world"
}
button {
// ✅ Since `string` is `Copy`, we can move it into the onclick handler again
onclick: move |_| println!("{}", string),
"Print hello world again"
}
}
}- Calling
cloneon your data before you move it into the closure:
// `MyComponent` accepts a string which doesn't implement `Copy`
#[component]
fn MyComponent(string: String) -> Element {
rsx! {
button {
// ✅ The string only has one owner. We could move it into this closure, but since we want to use the string in other closures later, we will clone it instead
onclick: {
// Clone the string in a new block
let string = string.clone();
// Then move the cloned string into the closure
move |_| println!("{}", string)
},
"Print hello world"
}
button {
// ✅ We don't use the string after this closure, so we can just move it into the closure directly
onclick: move |_| println!("{}", string),
"Print hello world again"
}
}
}Sourcefn onloadeddata<__Marker>(
self,
event_handler: impl EventHandlerValue<MediaData, __Marker>,
) -> <Self as AttributeBuilderTarget>::Output
fn onloadeddata<__Marker>( self, event_handler: impl EventHandlerValue<MediaData, __Marker>, ) -> <Self as AttributeBuilderTarget>::Output
onloadeddata
General Event Handler Information
§Event Handlers
Event Handlers let you react to user input in your application. In Dioxus, event handlers accept a closure that is called when the event occurs:
use dioxus::prelude::*;
fn App() -> Element {
rsx! {
button {
// The `onclick` event accepts a closure with the signature `fn(Event)`
onclick: |event_data| println!("clicked! I got the event data: {event_data:?}"),
"Click me"
}
}
}§Event Lifetimes
Events take a closure with the 'static lifetime. This means that the closure can only access data that either exists for the entire lifetime of the application, or data that you move into the closure.
State in dioxus is copy which makes it very easy to move into 'static closures like event handlers:
let mut count = use_signal(|| 0);
rsx! {
button {
// Since we added the `move` keyword, the closure will move the `count` signal into the closure
onclick: move |_| {
// This will panic because the `count` signal is not in scope
count.set(count() + 1);
},
"Click me"
}
};If you need to access data that is not Copy, you may need to clone the data before you move it into the closure:
// String is not `Copy`
let string = "hello world".to_string();
rsx! {
button {
// The string only has one owner. We could move it into this closure, but since we want to use the string in other closures later, we will clone it instead
onclick: {
// Clone the string in a new block
let string = string.clone();
// Then move the cloned string into the closure
move |_| println!("{}", string)
},
"Print hello world"
}
button {
// We don't use the string after this closure, so we can just move it into the closure directly
onclick: move |_| println!("{}", string),
"Print hello world again"
}
};§Async Event Handlers
In addition to closures that return nothing, you can also use async closures to handle events. If you return an async block from an event handler, dioxus will automatically spawn it:
use dioxus::prelude::*;
fn App() -> Element {
rsx! {
button {
// The `onclick` event can also accept a closure that returns an async block
onclick: move |_| async move {
tokio::time::sleep(std::time::Duration::from_secs(1)).await;
println!("You clicked the button one second ago!");
},
"Click me"
}
}
}§Compiler errors you may run into while using event handlers
function requires argument type to outlive `'static`
Event handler in Dioxus need only access data that can last for the entire lifetime of the application. That generally means data that is moved into the closure. If you get this error, you may have forgotten to add move to your closure.
Broken component:
// We return an Element which can last as long as the component is on the screen
fn App() -> Element {
// Signals are `Copy` which makes them very easy to move into `'static` closures like event handlers
let state = use_signal(|| "hello world".to_string());
rsx! {
button {
// ❌ Without `move`, rust will try to borrow the `state` signal which fails because the state signal is dropped at the end of the function
onclick: |_| {
println!("You clicked the button! The state is: {state}");
},
"Click me"
}
}
// The state signal is dropped here, but the event handler still needs to access it
}Fixed component:
fn App() -> Element {
let state = use_signal(|| "hello world".to_string());
rsx! {
button {
// ✅ The `move` keyword tells rust it can move the `state` signal into the closure. Since the closure owns the signal state, it can read it even after the function returns
onclick: move |_| {
println!("You clicked the button! The state is: {state}");
},
"Click me"
}
}
}use of moved value: `your_value` value used here after move
Data in rust has a single owner. If you run into this error, you have likely tried to move data that isn’t Copy into two different closures. You can fix this issue by making your data Copy or calling clone on it before you move it into the closure.
Broken component:
// `MyComponent` accepts a string which cannot be copied implicitly
#[component]
fn MyComponent(string: String) -> Element {
rsx! {
button {
// ❌ We are moving the string into the onclick handler which means we can't access it elsewhere
onclick: move |_| {
println!("{string}");
},
"Print hello world"
}
button {
// ❌ Since we already moved the string, we can't move it into the onclick handler again. This will cause a compiler error
onclick: move |_| {
println!("{string}");
},
"Print hello world again"
}
}
}You can fix this issue by either:
- Making your data
CopywithReadSignal:
// `MyComponent` accepts `ReadSignal<String>` which implements `Copy`
#[component]
fn MyComponent(string: ReadSignal<String>) -> Element {
rsx! {
button {
// ✅ Because the `string` signal is `Copy`, we can copy it into the closure while still having access to it elsewhere
onclick: move |_| println!("{}", string),
"Print hello world"
}
button {
// ✅ Since `string` is `Copy`, we can move it into the onclick handler again
onclick: move |_| println!("{}", string),
"Print hello world again"
}
}
}- Calling
cloneon your data before you move it into the closure:
// `MyComponent` accepts a string which doesn't implement `Copy`
#[component]
fn MyComponent(string: String) -> Element {
rsx! {
button {
// ✅ The string only has one owner. We could move it into this closure, but since we want to use the string in other closures later, we will clone it instead
onclick: {
// Clone the string in a new block
let string = string.clone();
// Then move the cloned string into the closure
move |_| println!("{}", string)
},
"Print hello world"
}
button {
// ✅ We don't use the string after this closure, so we can just move it into the closure directly
onclick: move |_| println!("{}", string),
"Print hello world again"
}
}
}Sourcefn onloadedmetadata<__Marker>(
self,
event_handler: impl EventHandlerValue<MediaData, __Marker>,
) -> <Self as AttributeBuilderTarget>::Output
fn onloadedmetadata<__Marker>( self, event_handler: impl EventHandlerValue<MediaData, __Marker>, ) -> <Self as AttributeBuilderTarget>::Output
onloadedmetadata
General Event Handler Information
§Event Handlers
Event Handlers let you react to user input in your application. In Dioxus, event handlers accept a closure that is called when the event occurs:
use dioxus::prelude::*;
fn App() -> Element {
rsx! {
button {
// The `onclick` event accepts a closure with the signature `fn(Event)`
onclick: |event_data| println!("clicked! I got the event data: {event_data:?}"),
"Click me"
}
}
}§Event Lifetimes
Events take a closure with the 'static lifetime. This means that the closure can only access data that either exists for the entire lifetime of the application, or data that you move into the closure.
State in dioxus is copy which makes it very easy to move into 'static closures like event handlers:
let mut count = use_signal(|| 0);
rsx! {
button {
// Since we added the `move` keyword, the closure will move the `count` signal into the closure
onclick: move |_| {
// This will panic because the `count` signal is not in scope
count.set(count() + 1);
},
"Click me"
}
};If you need to access data that is not Copy, you may need to clone the data before you move it into the closure:
// String is not `Copy`
let string = "hello world".to_string();
rsx! {
button {
// The string only has one owner. We could move it into this closure, but since we want to use the string in other closures later, we will clone it instead
onclick: {
// Clone the string in a new block
let string = string.clone();
// Then move the cloned string into the closure
move |_| println!("{}", string)
},
"Print hello world"
}
button {
// We don't use the string after this closure, so we can just move it into the closure directly
onclick: move |_| println!("{}", string),
"Print hello world again"
}
};§Async Event Handlers
In addition to closures that return nothing, you can also use async closures to handle events. If you return an async block from an event handler, dioxus will automatically spawn it:
use dioxus::prelude::*;
fn App() -> Element {
rsx! {
button {
// The `onclick` event can also accept a closure that returns an async block
onclick: move |_| async move {
tokio::time::sleep(std::time::Duration::from_secs(1)).await;
println!("You clicked the button one second ago!");
},
"Click me"
}
}
}§Compiler errors you may run into while using event handlers
function requires argument type to outlive `'static`
Event handler in Dioxus need only access data that can last for the entire lifetime of the application. That generally means data that is moved into the closure. If you get this error, you may have forgotten to add move to your closure.
Broken component:
// We return an Element which can last as long as the component is on the screen
fn App() -> Element {
// Signals are `Copy` which makes them very easy to move into `'static` closures like event handlers
let state = use_signal(|| "hello world".to_string());
rsx! {
button {
// ❌ Without `move`, rust will try to borrow the `state` signal which fails because the state signal is dropped at the end of the function
onclick: |_| {
println!("You clicked the button! The state is: {state}");
},
"Click me"
}
}
// The state signal is dropped here, but the event handler still needs to access it
}Fixed component:
fn App() -> Element {
let state = use_signal(|| "hello world".to_string());
rsx! {
button {
// ✅ The `move` keyword tells rust it can move the `state` signal into the closure. Since the closure owns the signal state, it can read it even after the function returns
onclick: move |_| {
println!("You clicked the button! The state is: {state}");
},
"Click me"
}
}
}use of moved value: `your_value` value used here after move
Data in rust has a single owner. If you run into this error, you have likely tried to move data that isn’t Copy into two different closures. You can fix this issue by making your data Copy or calling clone on it before you move it into the closure.
Broken component:
// `MyComponent` accepts a string which cannot be copied implicitly
#[component]
fn MyComponent(string: String) -> Element {
rsx! {
button {
// ❌ We are moving the string into the onclick handler which means we can't access it elsewhere
onclick: move |_| {
println!("{string}");
},
"Print hello world"
}
button {
// ❌ Since we already moved the string, we can't move it into the onclick handler again. This will cause a compiler error
onclick: move |_| {
println!("{string}");
},
"Print hello world again"
}
}
}You can fix this issue by either:
- Making your data
CopywithReadSignal:
// `MyComponent` accepts `ReadSignal<String>` which implements `Copy`
#[component]
fn MyComponent(string: ReadSignal<String>) -> Element {
rsx! {
button {
// ✅ Because the `string` signal is `Copy`, we can copy it into the closure while still having access to it elsewhere
onclick: move |_| println!("{}", string),
"Print hello world"
}
button {
// ✅ Since `string` is `Copy`, we can move it into the onclick handler again
onclick: move |_| println!("{}", string),
"Print hello world again"
}
}
}- Calling
cloneon your data before you move it into the closure:
// `MyComponent` accepts a string which doesn't implement `Copy`
#[component]
fn MyComponent(string: String) -> Element {
rsx! {
button {
// ✅ The string only has one owner. We could move it into this closure, but since we want to use the string in other closures later, we will clone it instead
onclick: {
// Clone the string in a new block
let string = string.clone();
// Then move the cloned string into the closure
move |_| println!("{}", string)
},
"Print hello world"
}
button {
// ✅ We don't use the string after this closure, so we can just move it into the closure directly
onclick: move |_| println!("{}", string),
"Print hello world again"
}
}
}Sourcefn onloadstart<__Marker>(
self,
event_handler: impl EventHandlerValue<MediaData, __Marker>,
) -> <Self as AttributeBuilderTarget>::Output
fn onloadstart<__Marker>( self, event_handler: impl EventHandlerValue<MediaData, __Marker>, ) -> <Self as AttributeBuilderTarget>::Output
onloadstart
General Event Handler Information
§Event Handlers
Event Handlers let you react to user input in your application. In Dioxus, event handlers accept a closure that is called when the event occurs:
use dioxus::prelude::*;
fn App() -> Element {
rsx! {
button {
// The `onclick` event accepts a closure with the signature `fn(Event)`
onclick: |event_data| println!("clicked! I got the event data: {event_data:?}"),
"Click me"
}
}
}§Event Lifetimes
Events take a closure with the 'static lifetime. This means that the closure can only access data that either exists for the entire lifetime of the application, or data that you move into the closure.
State in dioxus is copy which makes it very easy to move into 'static closures like event handlers:
let mut count = use_signal(|| 0);
rsx! {
button {
// Since we added the `move` keyword, the closure will move the `count` signal into the closure
onclick: move |_| {
// This will panic because the `count` signal is not in scope
count.set(count() + 1);
},
"Click me"
}
};If you need to access data that is not Copy, you may need to clone the data before you move it into the closure:
// String is not `Copy`
let string = "hello world".to_string();
rsx! {
button {
// The string only has one owner. We could move it into this closure, but since we want to use the string in other closures later, we will clone it instead
onclick: {
// Clone the string in a new block
let string = string.clone();
// Then move the cloned string into the closure
move |_| println!("{}", string)
},
"Print hello world"
}
button {
// We don't use the string after this closure, so we can just move it into the closure directly
onclick: move |_| println!("{}", string),
"Print hello world again"
}
};§Async Event Handlers
In addition to closures that return nothing, you can also use async closures to handle events. If you return an async block from an event handler, dioxus will automatically spawn it:
use dioxus::prelude::*;
fn App() -> Element {
rsx! {
button {
// The `onclick` event can also accept a closure that returns an async block
onclick: move |_| async move {
tokio::time::sleep(std::time::Duration::from_secs(1)).await;
println!("You clicked the button one second ago!");
},
"Click me"
}
}
}§Compiler errors you may run into while using event handlers
function requires argument type to outlive `'static`
Event handler in Dioxus need only access data that can last for the entire lifetime of the application. That generally means data that is moved into the closure. If you get this error, you may have forgotten to add move to your closure.
Broken component:
// We return an Element which can last as long as the component is on the screen
fn App() -> Element {
// Signals are `Copy` which makes them very easy to move into `'static` closures like event handlers
let state = use_signal(|| "hello world".to_string());
rsx! {
button {
// ❌ Without `move`, rust will try to borrow the `state` signal which fails because the state signal is dropped at the end of the function
onclick: |_| {
println!("You clicked the button! The state is: {state}");
},
"Click me"
}
}
// The state signal is dropped here, but the event handler still needs to access it
}Fixed component:
fn App() -> Element {
let state = use_signal(|| "hello world".to_string());
rsx! {
button {
// ✅ The `move` keyword tells rust it can move the `state` signal into the closure. Since the closure owns the signal state, it can read it even after the function returns
onclick: move |_| {
println!("You clicked the button! The state is: {state}");
},
"Click me"
}
}
}use of moved value: `your_value` value used here after move
Data in rust has a single owner. If you run into this error, you have likely tried to move data that isn’t Copy into two different closures. You can fix this issue by making your data Copy or calling clone on it before you move it into the closure.
Broken component:
// `MyComponent` accepts a string which cannot be copied implicitly
#[component]
fn MyComponent(string: String) -> Element {
rsx! {
button {
// ❌ We are moving the string into the onclick handler which means we can't access it elsewhere
onclick: move |_| {
println!("{string}");
},
"Print hello world"
}
button {
// ❌ Since we already moved the string, we can't move it into the onclick handler again. This will cause a compiler error
onclick: move |_| {
println!("{string}");
},
"Print hello world again"
}
}
}You can fix this issue by either:
- Making your data
CopywithReadSignal:
// `MyComponent` accepts `ReadSignal<String>` which implements `Copy`
#[component]
fn MyComponent(string: ReadSignal<String>) -> Element {
rsx! {
button {
// ✅ Because the `string` signal is `Copy`, we can copy it into the closure while still having access to it elsewhere
onclick: move |_| println!("{}", string),
"Print hello world"
}
button {
// ✅ Since `string` is `Copy`, we can move it into the onclick handler again
onclick: move |_| println!("{}", string),
"Print hello world again"
}
}
}- Calling
cloneon your data before you move it into the closure:
// `MyComponent` accepts a string which doesn't implement `Copy`
#[component]
fn MyComponent(string: String) -> Element {
rsx! {
button {
// ✅ The string only has one owner. We could move it into this closure, but since we want to use the string in other closures later, we will clone it instead
onclick: {
// Clone the string in a new block
let string = string.clone();
// Then move the cloned string into the closure
move |_| println!("{}", string)
},
"Print hello world"
}
button {
// ✅ We don't use the string after this closure, so we can just move it into the closure directly
onclick: move |_| println!("{}", string),
"Print hello world again"
}
}
}Sourcefn onpause<__Marker>(
self,
event_handler: impl EventHandlerValue<MediaData, __Marker>,
) -> <Self as AttributeBuilderTarget>::Output
fn onpause<__Marker>( self, event_handler: impl EventHandlerValue<MediaData, __Marker>, ) -> <Self as AttributeBuilderTarget>::Output
onpause
General Event Handler Information
§Event Handlers
Event Handlers let you react to user input in your application. In Dioxus, event handlers accept a closure that is called when the event occurs:
use dioxus::prelude::*;
fn App() -> Element {
rsx! {
button {
// The `onclick` event accepts a closure with the signature `fn(Event)`
onclick: |event_data| println!("clicked! I got the event data: {event_data:?}"),
"Click me"
}
}
}§Event Lifetimes
Events take a closure with the 'static lifetime. This means that the closure can only access data that either exists for the entire lifetime of the application, or data that you move into the closure.
State in dioxus is copy which makes it very easy to move into 'static closures like event handlers:
let mut count = use_signal(|| 0);
rsx! {
button {
// Since we added the `move` keyword, the closure will move the `count` signal into the closure
onclick: move |_| {
// This will panic because the `count` signal is not in scope
count.set(count() + 1);
},
"Click me"
}
};If you need to access data that is not Copy, you may need to clone the data before you move it into the closure:
// String is not `Copy`
let string = "hello world".to_string();
rsx! {
button {
// The string only has one owner. We could move it into this closure, but since we want to use the string in other closures later, we will clone it instead
onclick: {
// Clone the string in a new block
let string = string.clone();
// Then move the cloned string into the closure
move |_| println!("{}", string)
},
"Print hello world"
}
button {
// We don't use the string after this closure, so we can just move it into the closure directly
onclick: move |_| println!("{}", string),
"Print hello world again"
}
};§Async Event Handlers
In addition to closures that return nothing, you can also use async closures to handle events. If you return an async block from an event handler, dioxus will automatically spawn it:
use dioxus::prelude::*;
fn App() -> Element {
rsx! {
button {
// The `onclick` event can also accept a closure that returns an async block
onclick: move |_| async move {
tokio::time::sleep(std::time::Duration::from_secs(1)).await;
println!("You clicked the button one second ago!");
},
"Click me"
}
}
}§Compiler errors you may run into while using event handlers
function requires argument type to outlive `'static`
Event handler in Dioxus need only access data that can last for the entire lifetime of the application. That generally means data that is moved into the closure. If you get this error, you may have forgotten to add move to your closure.
Broken component:
// We return an Element which can last as long as the component is on the screen
fn App() -> Element {
// Signals are `Copy` which makes them very easy to move into `'static` closures like event handlers
let state = use_signal(|| "hello world".to_string());
rsx! {
button {
// ❌ Without `move`, rust will try to borrow the `state` signal which fails because the state signal is dropped at the end of the function
onclick: |_| {
println!("You clicked the button! The state is: {state}");
},
"Click me"
}
}
// The state signal is dropped here, but the event handler still needs to access it
}Fixed component:
fn App() -> Element {
let state = use_signal(|| "hello world".to_string());
rsx! {
button {
// ✅ The `move` keyword tells rust it can move the `state` signal into the closure. Since the closure owns the signal state, it can read it even after the function returns
onclick: move |_| {
println!("You clicked the button! The state is: {state}");
},
"Click me"
}
}
}use of moved value: `your_value` value used here after move
Data in rust has a single owner. If you run into this error, you have likely tried to move data that isn’t Copy into two different closures. You can fix this issue by making your data Copy or calling clone on it before you move it into the closure.
Broken component:
// `MyComponent` accepts a string which cannot be copied implicitly
#[component]
fn MyComponent(string: String) -> Element {
rsx! {
button {
// ❌ We are moving the string into the onclick handler which means we can't access it elsewhere
onclick: move |_| {
println!("{string}");
},
"Print hello world"
}
button {
// ❌ Since we already moved the string, we can't move it into the onclick handler again. This will cause a compiler error
onclick: move |_| {
println!("{string}");
},
"Print hello world again"
}
}
}You can fix this issue by either:
- Making your data
CopywithReadSignal:
// `MyComponent` accepts `ReadSignal<String>` which implements `Copy`
#[component]
fn MyComponent(string: ReadSignal<String>) -> Element {
rsx! {
button {
// ✅ Because the `string` signal is `Copy`, we can copy it into the closure while still having access to it elsewhere
onclick: move |_| println!("{}", string),
"Print hello world"
}
button {
// ✅ Since `string` is `Copy`, we can move it into the onclick handler again
onclick: move |_| println!("{}", string),
"Print hello world again"
}
}
}- Calling
cloneon your data before you move it into the closure:
// `MyComponent` accepts a string which doesn't implement `Copy`
#[component]
fn MyComponent(string: String) -> Element {
rsx! {
button {
// ✅ The string only has one owner. We could move it into this closure, but since we want to use the string in other closures later, we will clone it instead
onclick: {
// Clone the string in a new block
let string = string.clone();
// Then move the cloned string into the closure
move |_| println!("{}", string)
},
"Print hello world"
}
button {
// ✅ We don't use the string after this closure, so we can just move it into the closure directly
onclick: move |_| println!("{}", string),
"Print hello world again"
}
}
}Sourcefn onplay<__Marker>(
self,
event_handler: impl EventHandlerValue<MediaData, __Marker>,
) -> <Self as AttributeBuilderTarget>::Output
fn onplay<__Marker>( self, event_handler: impl EventHandlerValue<MediaData, __Marker>, ) -> <Self as AttributeBuilderTarget>::Output
onplay
General Event Handler Information
§Event Handlers
Event Handlers let you react to user input in your application. In Dioxus, event handlers accept a closure that is called when the event occurs:
use dioxus::prelude::*;
fn App() -> Element {
rsx! {
button {
// The `onclick` event accepts a closure with the signature `fn(Event)`
onclick: |event_data| println!("clicked! I got the event data: {event_data:?}"),
"Click me"
}
}
}§Event Lifetimes
Events take a closure with the 'static lifetime. This means that the closure can only access data that either exists for the entire lifetime of the application, or data that you move into the closure.
State in dioxus is copy which makes it very easy to move into 'static closures like event handlers:
let mut count = use_signal(|| 0);
rsx! {
button {
// Since we added the `move` keyword, the closure will move the `count` signal into the closure
onclick: move |_| {
// This will panic because the `count` signal is not in scope
count.set(count() + 1);
},
"Click me"
}
};If you need to access data that is not Copy, you may need to clone the data before you move it into the closure:
// String is not `Copy`
let string = "hello world".to_string();
rsx! {
button {
// The string only has one owner. We could move it into this closure, but since we want to use the string in other closures later, we will clone it instead
onclick: {
// Clone the string in a new block
let string = string.clone();
// Then move the cloned string into the closure
move |_| println!("{}", string)
},
"Print hello world"
}
button {
// We don't use the string after this closure, so we can just move it into the closure directly
onclick: move |_| println!("{}", string),
"Print hello world again"
}
};§Async Event Handlers
In addition to closures that return nothing, you can also use async closures to handle events. If you return an async block from an event handler, dioxus will automatically spawn it:
use dioxus::prelude::*;
fn App() -> Element {
rsx! {
button {
// The `onclick` event can also accept a closure that returns an async block
onclick: move |_| async move {
tokio::time::sleep(std::time::Duration::from_secs(1)).await;
println!("You clicked the button one second ago!");
},
"Click me"
}
}
}§Compiler errors you may run into while using event handlers
function requires argument type to outlive `'static`
Event handler in Dioxus need only access data that can last for the entire lifetime of the application. That generally means data that is moved into the closure. If you get this error, you may have forgotten to add move to your closure.
Broken component:
// We return an Element which can last as long as the component is on the screen
fn App() -> Element {
// Signals are `Copy` which makes them very easy to move into `'static` closures like event handlers
let state = use_signal(|| "hello world".to_string());
rsx! {
button {
// ❌ Without `move`, rust will try to borrow the `state` signal which fails because the state signal is dropped at the end of the function
onclick: |_| {
println!("You clicked the button! The state is: {state}");
},
"Click me"
}
}
// The state signal is dropped here, but the event handler still needs to access it
}Fixed component:
fn App() -> Element {
let state = use_signal(|| "hello world".to_string());
rsx! {
button {
// ✅ The `move` keyword tells rust it can move the `state` signal into the closure. Since the closure owns the signal state, it can read it even after the function returns
onclick: move |_| {
println!("You clicked the button! The state is: {state}");
},
"Click me"
}
}
}use of moved value: `your_value` value used here after move
Data in rust has a single owner. If you run into this error, you have likely tried to move data that isn’t Copy into two different closures. You can fix this issue by making your data Copy or calling clone on it before you move it into the closure.
Broken component:
// `MyComponent` accepts a string which cannot be copied implicitly
#[component]
fn MyComponent(string: String) -> Element {
rsx! {
button {
// ❌ We are moving the string into the onclick handler which means we can't access it elsewhere
onclick: move |_| {
println!("{string}");
},
"Print hello world"
}
button {
// ❌ Since we already moved the string, we can't move it into the onclick handler again. This will cause a compiler error
onclick: move |_| {
println!("{string}");
},
"Print hello world again"
}
}
}You can fix this issue by either:
- Making your data
CopywithReadSignal:
// `MyComponent` accepts `ReadSignal<String>` which implements `Copy`
#[component]
fn MyComponent(string: ReadSignal<String>) -> Element {
rsx! {
button {
// ✅ Because the `string` signal is `Copy`, we can copy it into the closure while still having access to it elsewhere
onclick: move |_| println!("{}", string),
"Print hello world"
}
button {
// ✅ Since `string` is `Copy`, we can move it into the onclick handler again
onclick: move |_| println!("{}", string),
"Print hello world again"
}
}
}- Calling
cloneon your data before you move it into the closure:
// `MyComponent` accepts a string which doesn't implement `Copy`
#[component]
fn MyComponent(string: String) -> Element {
rsx! {
button {
// ✅ The string only has one owner. We could move it into this closure, but since we want to use the string in other closures later, we will clone it instead
onclick: {
// Clone the string in a new block
let string = string.clone();
// Then move the cloned string into the closure
move |_| println!("{}", string)
},
"Print hello world"
}
button {
// ✅ We don't use the string after this closure, so we can just move it into the closure directly
onclick: move |_| println!("{}", string),
"Print hello world again"
}
}
}Sourcefn onplaying<__Marker>(
self,
event_handler: impl EventHandlerValue<MediaData, __Marker>,
) -> <Self as AttributeBuilderTarget>::Output
fn onplaying<__Marker>( self, event_handler: impl EventHandlerValue<MediaData, __Marker>, ) -> <Self as AttributeBuilderTarget>::Output
onplaying
General Event Handler Information
§Event Handlers
Event Handlers let you react to user input in your application. In Dioxus, event handlers accept a closure that is called when the event occurs:
use dioxus::prelude::*;
fn App() -> Element {
rsx! {
button {
// The `onclick` event accepts a closure with the signature `fn(Event)`
onclick: |event_data| println!("clicked! I got the event data: {event_data:?}"),
"Click me"
}
}
}§Event Lifetimes
Events take a closure with the 'static lifetime. This means that the closure can only access data that either exists for the entire lifetime of the application, or data that you move into the closure.
State in dioxus is copy which makes it very easy to move into 'static closures like event handlers:
let mut count = use_signal(|| 0);
rsx! {
button {
// Since we added the `move` keyword, the closure will move the `count` signal into the closure
onclick: move |_| {
// This will panic because the `count` signal is not in scope
count.set(count() + 1);
},
"Click me"
}
};If you need to access data that is not Copy, you may need to clone the data before you move it into the closure:
// String is not `Copy`
let string = "hello world".to_string();
rsx! {
button {
// The string only has one owner. We could move it into this closure, but since we want to use the string in other closures later, we will clone it instead
onclick: {
// Clone the string in a new block
let string = string.clone();
// Then move the cloned string into the closure
move |_| println!("{}", string)
},
"Print hello world"
}
button {
// We don't use the string after this closure, so we can just move it into the closure directly
onclick: move |_| println!("{}", string),
"Print hello world again"
}
};§Async Event Handlers
In addition to closures that return nothing, you can also use async closures to handle events. If you return an async block from an event handler, dioxus will automatically spawn it:
use dioxus::prelude::*;
fn App() -> Element {
rsx! {
button {
// The `onclick` event can also accept a closure that returns an async block
onclick: move |_| async move {
tokio::time::sleep(std::time::Duration::from_secs(1)).await;
println!("You clicked the button one second ago!");
},
"Click me"
}
}
}§Compiler errors you may run into while using event handlers
function requires argument type to outlive `'static`
Event handler in Dioxus need only access data that can last for the entire lifetime of the application. That generally means data that is moved into the closure. If you get this error, you may have forgotten to add move to your closure.
Broken component:
// We return an Element which can last as long as the component is on the screen
fn App() -> Element {
// Signals are `Copy` which makes them very easy to move into `'static` closures like event handlers
let state = use_signal(|| "hello world".to_string());
rsx! {
button {
// ❌ Without `move`, rust will try to borrow the `state` signal which fails because the state signal is dropped at the end of the function
onclick: |_| {
println!("You clicked the button! The state is: {state}");
},
"Click me"
}
}
// The state signal is dropped here, but the event handler still needs to access it
}Fixed component:
fn App() -> Element {
let state = use_signal(|| "hello world".to_string());
rsx! {
button {
// ✅ The `move` keyword tells rust it can move the `state` signal into the closure. Since the closure owns the signal state, it can read it even after the function returns
onclick: move |_| {
println!("You clicked the button! The state is: {state}");
},
"Click me"
}
}
}use of moved value: `your_value` value used here after move
Data in rust has a single owner. If you run into this error, you have likely tried to move data that isn’t Copy into two different closures. You can fix this issue by making your data Copy or calling clone on it before you move it into the closure.
Broken component:
// `MyComponent` accepts a string which cannot be copied implicitly
#[component]
fn MyComponent(string: String) -> Element {
rsx! {
button {
// ❌ We are moving the string into the onclick handler which means we can't access it elsewhere
onclick: move |_| {
println!("{string}");
},
"Print hello world"
}
button {
// ❌ Since we already moved the string, we can't move it into the onclick handler again. This will cause a compiler error
onclick: move |_| {
println!("{string}");
},
"Print hello world again"
}
}
}You can fix this issue by either:
- Making your data
CopywithReadSignal:
// `MyComponent` accepts `ReadSignal<String>` which implements `Copy`
#[component]
fn MyComponent(string: ReadSignal<String>) -> Element {
rsx! {
button {
// ✅ Because the `string` signal is `Copy`, we can copy it into the closure while still having access to it elsewhere
onclick: move |_| println!("{}", string),
"Print hello world"
}
button {
// ✅ Since `string` is `Copy`, we can move it into the onclick handler again
onclick: move |_| println!("{}", string),
"Print hello world again"
}
}
}- Calling
cloneon your data before you move it into the closure:
// `MyComponent` accepts a string which doesn't implement `Copy`
#[component]
fn MyComponent(string: String) -> Element {
rsx! {
button {
// ✅ The string only has one owner. We could move it into this closure, but since we want to use the string in other closures later, we will clone it instead
onclick: {
// Clone the string in a new block
let string = string.clone();
// Then move the cloned string into the closure
move |_| println!("{}", string)
},
"Print hello world"
}
button {
// ✅ We don't use the string after this closure, so we can just move it into the closure directly
onclick: move |_| println!("{}", string),
"Print hello world again"
}
}
}Sourcefn onprogress<__Marker>(
self,
event_handler: impl EventHandlerValue<MediaData, __Marker>,
) -> <Self as AttributeBuilderTarget>::Output
fn onprogress<__Marker>( self, event_handler: impl EventHandlerValue<MediaData, __Marker>, ) -> <Self as AttributeBuilderTarget>::Output
onprogress
General Event Handler Information
§Event Handlers
Event Handlers let you react to user input in your application. In Dioxus, event handlers accept a closure that is called when the event occurs:
use dioxus::prelude::*;
fn App() -> Element {
rsx! {
button {
// The `onclick` event accepts a closure with the signature `fn(Event)`
onclick: |event_data| println!("clicked! I got the event data: {event_data:?}"),
"Click me"
}
}
}§Event Lifetimes
Events take a closure with the 'static lifetime. This means that the closure can only access data that either exists for the entire lifetime of the application, or data that you move into the closure.
State in dioxus is copy which makes it very easy to move into 'static closures like event handlers:
let mut count = use_signal(|| 0);
rsx! {
button {
// Since we added the `move` keyword, the closure will move the `count` signal into the closure
onclick: move |_| {
// This will panic because the `count` signal is not in scope
count.set(count() + 1);
},
"Click me"
}
};If you need to access data that is not Copy, you may need to clone the data before you move it into the closure:
// String is not `Copy`
let string = "hello world".to_string();
rsx! {
button {
// The string only has one owner. We could move it into this closure, but since we want to use the string in other closures later, we will clone it instead
onclick: {
// Clone the string in a new block
let string = string.clone();
// Then move the cloned string into the closure
move |_| println!("{}", string)
},
"Print hello world"
}
button {
// We don't use the string after this closure, so we can just move it into the closure directly
onclick: move |_| println!("{}", string),
"Print hello world again"
}
};§Async Event Handlers
In addition to closures that return nothing, you can also use async closures to handle events. If you return an async block from an event handler, dioxus will automatically spawn it:
use dioxus::prelude::*;
fn App() -> Element {
rsx! {
button {
// The `onclick` event can also accept a closure that returns an async block
onclick: move |_| async move {
tokio::time::sleep(std::time::Duration::from_secs(1)).await;
println!("You clicked the button one second ago!");
},
"Click me"
}
}
}§Compiler errors you may run into while using event handlers
function requires argument type to outlive `'static`
Event handler in Dioxus need only access data that can last for the entire lifetime of the application. That generally means data that is moved into the closure. If you get this error, you may have forgotten to add move to your closure.
Broken component:
// We return an Element which can last as long as the component is on the screen
fn App() -> Element {
// Signals are `Copy` which makes them very easy to move into `'static` closures like event handlers
let state = use_signal(|| "hello world".to_string());
rsx! {
button {
// ❌ Without `move`, rust will try to borrow the `state` signal which fails because the state signal is dropped at the end of the function
onclick: |_| {
println!("You clicked the button! The state is: {state}");
},
"Click me"
}
}
// The state signal is dropped here, but the event handler still needs to access it
}Fixed component:
fn App() -> Element {
let state = use_signal(|| "hello world".to_string());
rsx! {
button {
// ✅ The `move` keyword tells rust it can move the `state` signal into the closure. Since the closure owns the signal state, it can read it even after the function returns
onclick: move |_| {
println!("You clicked the button! The state is: {state}");
},
"Click me"
}
}
}use of moved value: `your_value` value used here after move
Data in rust has a single owner. If you run into this error, you have likely tried to move data that isn’t Copy into two different closures. You can fix this issue by making your data Copy or calling clone on it before you move it into the closure.
Broken component:
// `MyComponent` accepts a string which cannot be copied implicitly
#[component]
fn MyComponent(string: String) -> Element {
rsx! {
button {
// ❌ We are moving the string into the onclick handler which means we can't access it elsewhere
onclick: move |_| {
println!("{string}");
},
"Print hello world"
}
button {
// ❌ Since we already moved the string, we can't move it into the onclick handler again. This will cause a compiler error
onclick: move |_| {
println!("{string}");
},
"Print hello world again"
}
}
}You can fix this issue by either:
- Making your data
CopywithReadSignal:
// `MyComponent` accepts `ReadSignal<String>` which implements `Copy`
#[component]
fn MyComponent(string: ReadSignal<String>) -> Element {
rsx! {
button {
// ✅ Because the `string` signal is `Copy`, we can copy it into the closure while still having access to it elsewhere
onclick: move |_| println!("{}", string),
"Print hello world"
}
button {
// ✅ Since `string` is `Copy`, we can move it into the onclick handler again
onclick: move |_| println!("{}", string),
"Print hello world again"
}
}
}- Calling
cloneon your data before you move it into the closure:
// `MyComponent` accepts a string which doesn't implement `Copy`
#[component]
fn MyComponent(string: String) -> Element {
rsx! {
button {
// ✅ The string only has one owner. We could move it into this closure, but since we want to use the string in other closures later, we will clone it instead
onclick: {
// Clone the string in a new block
let string = string.clone();
// Then move the cloned string into the closure
move |_| println!("{}", string)
},
"Print hello world"
}
button {
// ✅ We don't use the string after this closure, so we can just move it into the closure directly
onclick: move |_| println!("{}", string),
"Print hello world again"
}
}
}Sourcefn onratechange<__Marker>(
self,
event_handler: impl EventHandlerValue<MediaData, __Marker>,
) -> <Self as AttributeBuilderTarget>::Output
fn onratechange<__Marker>( self, event_handler: impl EventHandlerValue<MediaData, __Marker>, ) -> <Self as AttributeBuilderTarget>::Output
onratechange
General Event Handler Information
§Event Handlers
Event Handlers let you react to user input in your application. In Dioxus, event handlers accept a closure that is called when the event occurs:
use dioxus::prelude::*;
fn App() -> Element {
rsx! {
button {
// The `onclick` event accepts a closure with the signature `fn(Event)`
onclick: |event_data| println!("clicked! I got the event data: {event_data:?}"),
"Click me"
}
}
}§Event Lifetimes
Events take a closure with the 'static lifetime. This means that the closure can only access data that either exists for the entire lifetime of the application, or data that you move into the closure.
State in dioxus is copy which makes it very easy to move into 'static closures like event handlers:
let mut count = use_signal(|| 0);
rsx! {
button {
// Since we added the `move` keyword, the closure will move the `count` signal into the closure
onclick: move |_| {
// This will panic because the `count` signal is not in scope
count.set(count() + 1);
},
"Click me"
}
};If you need to access data that is not Copy, you may need to clone the data before you move it into the closure:
// String is not `Copy`
let string = "hello world".to_string();
rsx! {
button {
// The string only has one owner. We could move it into this closure, but since we want to use the string in other closures later, we will clone it instead
onclick: {
// Clone the string in a new block
let string = string.clone();
// Then move the cloned string into the closure
move |_| println!("{}", string)
},
"Print hello world"
}
button {
// We don't use the string after this closure, so we can just move it into the closure directly
onclick: move |_| println!("{}", string),
"Print hello world again"
}
};§Async Event Handlers
In addition to closures that return nothing, you can also use async closures to handle events. If you return an async block from an event handler, dioxus will automatically spawn it:
use dioxus::prelude::*;
fn App() -> Element {
rsx! {
button {
// The `onclick` event can also accept a closure that returns an async block
onclick: move |_| async move {
tokio::time::sleep(std::time::Duration::from_secs(1)).await;
println!("You clicked the button one second ago!");
},
"Click me"
}
}
}§Compiler errors you may run into while using event handlers
function requires argument type to outlive `'static`
Event handler in Dioxus need only access data that can last for the entire lifetime of the application. That generally means data that is moved into the closure. If you get this error, you may have forgotten to add move to your closure.
Broken component:
// We return an Element which can last as long as the component is on the screen
fn App() -> Element {
// Signals are `Copy` which makes them very easy to move into `'static` closures like event handlers
let state = use_signal(|| "hello world".to_string());
rsx! {
button {
// ❌ Without `move`, rust will try to borrow the `state` signal which fails because the state signal is dropped at the end of the function
onclick: |_| {
println!("You clicked the button! The state is: {state}");
},
"Click me"
}
}
// The state signal is dropped here, but the event handler still needs to access it
}Fixed component:
fn App() -> Element {
let state = use_signal(|| "hello world".to_string());
rsx! {
button {
// ✅ The `move` keyword tells rust it can move the `state` signal into the closure. Since the closure owns the signal state, it can read it even after the function returns
onclick: move |_| {
println!("You clicked the button! The state is: {state}");
},
"Click me"
}
}
}use of moved value: `your_value` value used here after move
Data in rust has a single owner. If you run into this error, you have likely tried to move data that isn’t Copy into two different closures. You can fix this issue by making your data Copy or calling clone on it before you move it into the closure.
Broken component:
// `MyComponent` accepts a string which cannot be copied implicitly
#[component]
fn MyComponent(string: String) -> Element {
rsx! {
button {
// ❌ We are moving the string into the onclick handler which means we can't access it elsewhere
onclick: move |_| {
println!("{string}");
},
"Print hello world"
}
button {
// ❌ Since we already moved the string, we can't move it into the onclick handler again. This will cause a compiler error
onclick: move |_| {
println!("{string}");
},
"Print hello world again"
}
}
}You can fix this issue by either:
- Making your data
CopywithReadSignal:
// `MyComponent` accepts `ReadSignal<String>` which implements `Copy`
#[component]
fn MyComponent(string: ReadSignal<String>) -> Element {
rsx! {
button {
// ✅ Because the `string` signal is `Copy`, we can copy it into the closure while still having access to it elsewhere
onclick: move |_| println!("{}", string),
"Print hello world"
}
button {
// ✅ Since `string` is `Copy`, we can move it into the onclick handler again
onclick: move |_| println!("{}", string),
"Print hello world again"
}
}
}- Calling
cloneon your data before you move it into the closure:
// `MyComponent` accepts a string which doesn't implement `Copy`
#[component]
fn MyComponent(string: String) -> Element {
rsx! {
button {
// ✅ The string only has one owner. We could move it into this closure, but since we want to use the string in other closures later, we will clone it instead
onclick: {
// Clone the string in a new block
let string = string.clone();
// Then move the cloned string into the closure
move |_| println!("{}", string)
},
"Print hello world"
}
button {
// ✅ We don't use the string after this closure, so we can just move it into the closure directly
onclick: move |_| println!("{}", string),
"Print hello world again"
}
}
}Sourcefn onseeked<__Marker>(
self,
event_handler: impl EventHandlerValue<MediaData, __Marker>,
) -> <Self as AttributeBuilderTarget>::Output
fn onseeked<__Marker>( self, event_handler: impl EventHandlerValue<MediaData, __Marker>, ) -> <Self as AttributeBuilderTarget>::Output
onseeked
General Event Handler Information
§Event Handlers
Event Handlers let you react to user input in your application. In Dioxus, event handlers accept a closure that is called when the event occurs:
use dioxus::prelude::*;
fn App() -> Element {
rsx! {
button {
// The `onclick` event accepts a closure with the signature `fn(Event)`
onclick: |event_data| println!("clicked! I got the event data: {event_data:?}"),
"Click me"
}
}
}§Event Lifetimes
Events take a closure with the 'static lifetime. This means that the closure can only access data that either exists for the entire lifetime of the application, or data that you move into the closure.
State in dioxus is copy which makes it very easy to move into 'static closures like event handlers:
let mut count = use_signal(|| 0);
rsx! {
button {
// Since we added the `move` keyword, the closure will move the `count` signal into the closure
onclick: move |_| {
// This will panic because the `count` signal is not in scope
count.set(count() + 1);
},
"Click me"
}
};If you need to access data that is not Copy, you may need to clone the data before you move it into the closure:
// String is not `Copy`
let string = "hello world".to_string();
rsx! {
button {
// The string only has one owner. We could move it into this closure, but since we want to use the string in other closures later, we will clone it instead
onclick: {
// Clone the string in a new block
let string = string.clone();
// Then move the cloned string into the closure
move |_| println!("{}", string)
},
"Print hello world"
}
button {
// We don't use the string after this closure, so we can just move it into the closure directly
onclick: move |_| println!("{}", string),
"Print hello world again"
}
};§Async Event Handlers
In addition to closures that return nothing, you can also use async closures to handle events. If you return an async block from an event handler, dioxus will automatically spawn it:
use dioxus::prelude::*;
fn App() -> Element {
rsx! {
button {
// The `onclick` event can also accept a closure that returns an async block
onclick: move |_| async move {
tokio::time::sleep(std::time::Duration::from_secs(1)).await;
println!("You clicked the button one second ago!");
},
"Click me"
}
}
}§Compiler errors you may run into while using event handlers
function requires argument type to outlive `'static`
Event handler in Dioxus need only access data that can last for the entire lifetime of the application. That generally means data that is moved into the closure. If you get this error, you may have forgotten to add move to your closure.
Broken component:
// We return an Element which can last as long as the component is on the screen
fn App() -> Element {
// Signals are `Copy` which makes them very easy to move into `'static` closures like event handlers
let state = use_signal(|| "hello world".to_string());
rsx! {
button {
// ❌ Without `move`, rust will try to borrow the `state` signal which fails because the state signal is dropped at the end of the function
onclick: |_| {
println!("You clicked the button! The state is: {state}");
},
"Click me"
}
}
// The state signal is dropped here, but the event handler still needs to access it
}Fixed component:
fn App() -> Element {
let state = use_signal(|| "hello world".to_string());
rsx! {
button {
// ✅ The `move` keyword tells rust it can move the `state` signal into the closure. Since the closure owns the signal state, it can read it even after the function returns
onclick: move |_| {
println!("You clicked the button! The state is: {state}");
},
"Click me"
}
}
}use of moved value: `your_value` value used here after move
Data in rust has a single owner. If you run into this error, you have likely tried to move data that isn’t Copy into two different closures. You can fix this issue by making your data Copy or calling clone on it before you move it into the closure.
Broken component:
// `MyComponent` accepts a string which cannot be copied implicitly
#[component]
fn MyComponent(string: String) -> Element {
rsx! {
button {
// ❌ We are moving the string into the onclick handler which means we can't access it elsewhere
onclick: move |_| {
println!("{string}");
},
"Print hello world"
}
button {
// ❌ Since we already moved the string, we can't move it into the onclick handler again. This will cause a compiler error
onclick: move |_| {
println!("{string}");
},
"Print hello world again"
}
}
}You can fix this issue by either:
- Making your data
CopywithReadSignal:
// `MyComponent` accepts `ReadSignal<String>` which implements `Copy`
#[component]
fn MyComponent(string: ReadSignal<String>) -> Element {
rsx! {
button {
// ✅ Because the `string` signal is `Copy`, we can copy it into the closure while still having access to it elsewhere
onclick: move |_| println!("{}", string),
"Print hello world"
}
button {
// ✅ Since `string` is `Copy`, we can move it into the onclick handler again
onclick: move |_| println!("{}", string),
"Print hello world again"
}
}
}- Calling
cloneon your data before you move it into the closure:
// `MyComponent` accepts a string which doesn't implement `Copy`
#[component]
fn MyComponent(string: String) -> Element {
rsx! {
button {
// ✅ The string only has one owner. We could move it into this closure, but since we want to use the string in other closures later, we will clone it instead
onclick: {
// Clone the string in a new block
let string = string.clone();
// Then move the cloned string into the closure
move |_| println!("{}", string)
},
"Print hello world"
}
button {
// ✅ We don't use the string after this closure, so we can just move it into the closure directly
onclick: move |_| println!("{}", string),
"Print hello world again"
}
}
}Sourcefn onseeking<__Marker>(
self,
event_handler: impl EventHandlerValue<MediaData, __Marker>,
) -> <Self as AttributeBuilderTarget>::Output
fn onseeking<__Marker>( self, event_handler: impl EventHandlerValue<MediaData, __Marker>, ) -> <Self as AttributeBuilderTarget>::Output
onseeking
General Event Handler Information
§Event Handlers
Event Handlers let you react to user input in your application. In Dioxus, event handlers accept a closure that is called when the event occurs:
use dioxus::prelude::*;
fn App() -> Element {
rsx! {
button {
// The `onclick` event accepts a closure with the signature `fn(Event)`
onclick: |event_data| println!("clicked! I got the event data: {event_data:?}"),
"Click me"
}
}
}§Event Lifetimes
Events take a closure with the 'static lifetime. This means that the closure can only access data that either exists for the entire lifetime of the application, or data that you move into the closure.
State in dioxus is copy which makes it very easy to move into 'static closures like event handlers:
let mut count = use_signal(|| 0);
rsx! {
button {
// Since we added the `move` keyword, the closure will move the `count` signal into the closure
onclick: move |_| {
// This will panic because the `count` signal is not in scope
count.set(count() + 1);
},
"Click me"
}
};If you need to access data that is not Copy, you may need to clone the data before you move it into the closure:
// String is not `Copy`
let string = "hello world".to_string();
rsx! {
button {
// The string only has one owner. We could move it into this closure, but since we want to use the string in other closures later, we will clone it instead
onclick: {
// Clone the string in a new block
let string = string.clone();
// Then move the cloned string into the closure
move |_| println!("{}", string)
},
"Print hello world"
}
button {
// We don't use the string after this closure, so we can just move it into the closure directly
onclick: move |_| println!("{}", string),
"Print hello world again"
}
};§Async Event Handlers
In addition to closures that return nothing, you can also use async closures to handle events. If you return an async block from an event handler, dioxus will automatically spawn it:
use dioxus::prelude::*;
fn App() -> Element {
rsx! {
button {
// The `onclick` event can also accept a closure that returns an async block
onclick: move |_| async move {
tokio::time::sleep(std::time::Duration::from_secs(1)).await;
println!("You clicked the button one second ago!");
},
"Click me"
}
}
}§Compiler errors you may run into while using event handlers
function requires argument type to outlive `'static`
Event handler in Dioxus need only access data that can last for the entire lifetime of the application. That generally means data that is moved into the closure. If you get this error, you may have forgotten to add move to your closure.
Broken component:
// We return an Element which can last as long as the component is on the screen
fn App() -> Element {
// Signals are `Copy` which makes them very easy to move into `'static` closures like event handlers
let state = use_signal(|| "hello world".to_string());
rsx! {
button {
// ❌ Without `move`, rust will try to borrow the `state` signal which fails because the state signal is dropped at the end of the function
onclick: |_| {
println!("You clicked the button! The state is: {state}");
},
"Click me"
}
}
// The state signal is dropped here, but the event handler still needs to access it
}Fixed component:
fn App() -> Element {
let state = use_signal(|| "hello world".to_string());
rsx! {
button {
// ✅ The `move` keyword tells rust it can move the `state` signal into the closure. Since the closure owns the signal state, it can read it even after the function returns
onclick: move |_| {
println!("You clicked the button! The state is: {state}");
},
"Click me"
}
}
}use of moved value: `your_value` value used here after move
Data in rust has a single owner. If you run into this error, you have likely tried to move data that isn’t Copy into two different closures. You can fix this issue by making your data Copy or calling clone on it before you move it into the closure.
Broken component:
// `MyComponent` accepts a string which cannot be copied implicitly
#[component]
fn MyComponent(string: String) -> Element {
rsx! {
button {
// ❌ We are moving the string into the onclick handler which means we can't access it elsewhere
onclick: move |_| {
println!("{string}");
},
"Print hello world"
}
button {
// ❌ Since we already moved the string, we can't move it into the onclick handler again. This will cause a compiler error
onclick: move |_| {
println!("{string}");
},
"Print hello world again"
}
}
}You can fix this issue by either:
- Making your data
CopywithReadSignal:
// `MyComponent` accepts `ReadSignal<String>` which implements `Copy`
#[component]
fn MyComponent(string: ReadSignal<String>) -> Element {
rsx! {
button {
// ✅ Because the `string` signal is `Copy`, we can copy it into the closure while still having access to it elsewhere
onclick: move |_| println!("{}", string),
"Print hello world"
}
button {
// ✅ Since `string` is `Copy`, we can move it into the onclick handler again
onclick: move |_| println!("{}", string),
"Print hello world again"
}
}
}- Calling
cloneon your data before you move it into the closure:
// `MyComponent` accepts a string which doesn't implement `Copy`
#[component]
fn MyComponent(string: String) -> Element {
rsx! {
button {
// ✅ The string only has one owner. We could move it into this closure, but since we want to use the string in other closures later, we will clone it instead
onclick: {
// Clone the string in a new block
let string = string.clone();
// Then move the cloned string into the closure
move |_| println!("{}", string)
},
"Print hello world"
}
button {
// ✅ We don't use the string after this closure, so we can just move it into the closure directly
onclick: move |_| println!("{}", string),
"Print hello world again"
}
}
}Sourcefn onstalled<__Marker>(
self,
event_handler: impl EventHandlerValue<MediaData, __Marker>,
) -> <Self as AttributeBuilderTarget>::Output
fn onstalled<__Marker>( self, event_handler: impl EventHandlerValue<MediaData, __Marker>, ) -> <Self as AttributeBuilderTarget>::Output
onstalled
General Event Handler Information
§Event Handlers
Event Handlers let you react to user input in your application. In Dioxus, event handlers accept a closure that is called when the event occurs:
use dioxus::prelude::*;
fn App() -> Element {
rsx! {
button {
// The `onclick` event accepts a closure with the signature `fn(Event)`
onclick: |event_data| println!("clicked! I got the event data: {event_data:?}"),
"Click me"
}
}
}§Event Lifetimes
Events take a closure with the 'static lifetime. This means that the closure can only access data that either exists for the entire lifetime of the application, or data that you move into the closure.
State in dioxus is copy which makes it very easy to move into 'static closures like event handlers:
let mut count = use_signal(|| 0);
rsx! {
button {
// Since we added the `move` keyword, the closure will move the `count` signal into the closure
onclick: move |_| {
// This will panic because the `count` signal is not in scope
count.set(count() + 1);
},
"Click me"
}
};If you need to access data that is not Copy, you may need to clone the data before you move it into the closure:
// String is not `Copy`
let string = "hello world".to_string();
rsx! {
button {
// The string only has one owner. We could move it into this closure, but since we want to use the string in other closures later, we will clone it instead
onclick: {
// Clone the string in a new block
let string = string.clone();
// Then move the cloned string into the closure
move |_| println!("{}", string)
},
"Print hello world"
}
button {
// We don't use the string after this closure, so we can just move it into the closure directly
onclick: move |_| println!("{}", string),
"Print hello world again"
}
};§Async Event Handlers
In addition to closures that return nothing, you can also use async closures to handle events. If you return an async block from an event handler, dioxus will automatically spawn it:
use dioxus::prelude::*;
fn App() -> Element {
rsx! {
button {
// The `onclick` event can also accept a closure that returns an async block
onclick: move |_| async move {
tokio::time::sleep(std::time::Duration::from_secs(1)).await;
println!("You clicked the button one second ago!");
},
"Click me"
}
}
}§Compiler errors you may run into while using event handlers
function requires argument type to outlive `'static`
Event handler in Dioxus need only access data that can last for the entire lifetime of the application. That generally means data that is moved into the closure. If you get this error, you may have forgotten to add move to your closure.
Broken component:
// We return an Element which can last as long as the component is on the screen
fn App() -> Element {
// Signals are `Copy` which makes them very easy to move into `'static` closures like event handlers
let state = use_signal(|| "hello world".to_string());
rsx! {
button {
// ❌ Without `move`, rust will try to borrow the `state` signal which fails because the state signal is dropped at the end of the function
onclick: |_| {
println!("You clicked the button! The state is: {state}");
},
"Click me"
}
}
// The state signal is dropped here, but the event handler still needs to access it
}Fixed component:
fn App() -> Element {
let state = use_signal(|| "hello world".to_string());
rsx! {
button {
// ✅ The `move` keyword tells rust it can move the `state` signal into the closure. Since the closure owns the signal state, it can read it even after the function returns
onclick: move |_| {
println!("You clicked the button! The state is: {state}");
},
"Click me"
}
}
}use of moved value: `your_value` value used here after move
Data in rust has a single owner. If you run into this error, you have likely tried to move data that isn’t Copy into two different closures. You can fix this issue by making your data Copy or calling clone on it before you move it into the closure.
Broken component:
// `MyComponent` accepts a string which cannot be copied implicitly
#[component]
fn MyComponent(string: String) -> Element {
rsx! {
button {
// ❌ We are moving the string into the onclick handler which means we can't access it elsewhere
onclick: move |_| {
println!("{string}");
},
"Print hello world"
}
button {
// ❌ Since we already moved the string, we can't move it into the onclick handler again. This will cause a compiler error
onclick: move |_| {
println!("{string}");
},
"Print hello world again"
}
}
}You can fix this issue by either:
- Making your data
CopywithReadSignal:
// `MyComponent` accepts `ReadSignal<String>` which implements `Copy`
#[component]
fn MyComponent(string: ReadSignal<String>) -> Element {
rsx! {
button {
// ✅ Because the `string` signal is `Copy`, we can copy it into the closure while still having access to it elsewhere
onclick: move |_| println!("{}", string),
"Print hello world"
}
button {
// ✅ Since `string` is `Copy`, we can move it into the onclick handler again
onclick: move |_| println!("{}", string),
"Print hello world again"
}
}
}- Calling
cloneon your data before you move it into the closure:
// `MyComponent` accepts a string which doesn't implement `Copy`
#[component]
fn MyComponent(string: String) -> Element {
rsx! {
button {
// ✅ The string only has one owner. We could move it into this closure, but since we want to use the string in other closures later, we will clone it instead
onclick: {
// Clone the string in a new block
let string = string.clone();
// Then move the cloned string into the closure
move |_| println!("{}", string)
},
"Print hello world"
}
button {
// ✅ We don't use the string after this closure, so we can just move it into the closure directly
onclick: move |_| println!("{}", string),
"Print hello world again"
}
}
}Sourcefn onsuspend<__Marker>(
self,
event_handler: impl EventHandlerValue<MediaData, __Marker>,
) -> <Self as AttributeBuilderTarget>::Output
fn onsuspend<__Marker>( self, event_handler: impl EventHandlerValue<MediaData, __Marker>, ) -> <Self as AttributeBuilderTarget>::Output
onsuspend
General Event Handler Information
§Event Handlers
Event Handlers let you react to user input in your application. In Dioxus, event handlers accept a closure that is called when the event occurs:
use dioxus::prelude::*;
fn App() -> Element {
rsx! {
button {
// The `onclick` event accepts a closure with the signature `fn(Event)`
onclick: |event_data| println!("clicked! I got the event data: {event_data:?}"),
"Click me"
}
}
}§Event Lifetimes
Events take a closure with the 'static lifetime. This means that the closure can only access data that either exists for the entire lifetime of the application, or data that you move into the closure.
State in dioxus is copy which makes it very easy to move into 'static closures like event handlers:
let mut count = use_signal(|| 0);
rsx! {
button {
// Since we added the `move` keyword, the closure will move the `count` signal into the closure
onclick: move |_| {
// This will panic because the `count` signal is not in scope
count.set(count() + 1);
},
"Click me"
}
};If you need to access data that is not Copy, you may need to clone the data before you move it into the closure:
// String is not `Copy`
let string = "hello world".to_string();
rsx! {
button {
// The string only has one owner. We could move it into this closure, but since we want to use the string in other closures later, we will clone it instead
onclick: {
// Clone the string in a new block
let string = string.clone();
// Then move the cloned string into the closure
move |_| println!("{}", string)
},
"Print hello world"
}
button {
// We don't use the string after this closure, so we can just move it into the closure directly
onclick: move |_| println!("{}", string),
"Print hello world again"
}
};§Async Event Handlers
In addition to closures that return nothing, you can also use async closures to handle events. If you return an async block from an event handler, dioxus will automatically spawn it:
use dioxus::prelude::*;
fn App() -> Element {
rsx! {
button {
// The `onclick` event can also accept a closure that returns an async block
onclick: move |_| async move {
tokio::time::sleep(std::time::Duration::from_secs(1)).await;
println!("You clicked the button one second ago!");
},
"Click me"
}
}
}§Compiler errors you may run into while using event handlers
function requires argument type to outlive `'static`
Event handler in Dioxus need only access data that can last for the entire lifetime of the application. That generally means data that is moved into the closure. If you get this error, you may have forgotten to add move to your closure.
Broken component:
// We return an Element which can last as long as the component is on the screen
fn App() -> Element {
// Signals are `Copy` which makes them very easy to move into `'static` closures like event handlers
let state = use_signal(|| "hello world".to_string());
rsx! {
button {
// ❌ Without `move`, rust will try to borrow the `state` signal which fails because the state signal is dropped at the end of the function
onclick: |_| {
println!("You clicked the button! The state is: {state}");
},
"Click me"
}
}
// The state signal is dropped here, but the event handler still needs to access it
}Fixed component:
fn App() -> Element {
let state = use_signal(|| "hello world".to_string());
rsx! {
button {
// ✅ The `move` keyword tells rust it can move the `state` signal into the closure. Since the closure owns the signal state, it can read it even after the function returns
onclick: move |_| {
println!("You clicked the button! The state is: {state}");
},
"Click me"
}
}
}use of moved value: `your_value` value used here after move
Data in rust has a single owner. If you run into this error, you have likely tried to move data that isn’t Copy into two different closures. You can fix this issue by making your data Copy or calling clone on it before you move it into the closure.
Broken component:
// `MyComponent` accepts a string which cannot be copied implicitly
#[component]
fn MyComponent(string: String) -> Element {
rsx! {
button {
// ❌ We are moving the string into the onclick handler which means we can't access it elsewhere
onclick: move |_| {
println!("{string}");
},
"Print hello world"
}
button {
// ❌ Since we already moved the string, we can't move it into the onclick handler again. This will cause a compiler error
onclick: move |_| {
println!("{string}");
},
"Print hello world again"
}
}
}You can fix this issue by either:
- Making your data
CopywithReadSignal:
// `MyComponent` accepts `ReadSignal<String>` which implements `Copy`
#[component]
fn MyComponent(string: ReadSignal<String>) -> Element {
rsx! {
button {
// ✅ Because the `string` signal is `Copy`, we can copy it into the closure while still having access to it elsewhere
onclick: move |_| println!("{}", string),
"Print hello world"
}
button {
// ✅ Since `string` is `Copy`, we can move it into the onclick handler again
onclick: move |_| println!("{}", string),
"Print hello world again"
}
}
}- Calling
cloneon your data before you move it into the closure:
// `MyComponent` accepts a string which doesn't implement `Copy`
#[component]
fn MyComponent(string: String) -> Element {
rsx! {
button {
// ✅ The string only has one owner. We could move it into this closure, but since we want to use the string in other closures later, we will clone it instead
onclick: {
// Clone the string in a new block
let string = string.clone();
// Then move the cloned string into the closure
move |_| println!("{}", string)
},
"Print hello world"
}
button {
// ✅ We don't use the string after this closure, so we can just move it into the closure directly
onclick: move |_| println!("{}", string),
"Print hello world again"
}
}
}Sourcefn ontimeupdate<__Marker>(
self,
event_handler: impl EventHandlerValue<MediaData, __Marker>,
) -> <Self as AttributeBuilderTarget>::Output
fn ontimeupdate<__Marker>( self, event_handler: impl EventHandlerValue<MediaData, __Marker>, ) -> <Self as AttributeBuilderTarget>::Output
ontimeupdate
General Event Handler Information
§Event Handlers
Event Handlers let you react to user input in your application. In Dioxus, event handlers accept a closure that is called when the event occurs:
use dioxus::prelude::*;
fn App() -> Element {
rsx! {
button {
// The `onclick` event accepts a closure with the signature `fn(Event)`
onclick: |event_data| println!("clicked! I got the event data: {event_data:?}"),
"Click me"
}
}
}§Event Lifetimes
Events take a closure with the 'static lifetime. This means that the closure can only access data that either exists for the entire lifetime of the application, or data that you move into the closure.
State in dioxus is copy which makes it very easy to move into 'static closures like event handlers:
let mut count = use_signal(|| 0);
rsx! {
button {
// Since we added the `move` keyword, the closure will move the `count` signal into the closure
onclick: move |_| {
// This will panic because the `count` signal is not in scope
count.set(count() + 1);
},
"Click me"
}
};If you need to access data that is not Copy, you may need to clone the data before you move it into the closure:
// String is not `Copy`
let string = "hello world".to_string();
rsx! {
button {
// The string only has one owner. We could move it into this closure, but since we want to use the string in other closures later, we will clone it instead
onclick: {
// Clone the string in a new block
let string = string.clone();
// Then move the cloned string into the closure
move |_| println!("{}", string)
},
"Print hello world"
}
button {
// We don't use the string after this closure, so we can just move it into the closure directly
onclick: move |_| println!("{}", string),
"Print hello world again"
}
};§Async Event Handlers
In addition to closures that return nothing, you can also use async closures to handle events. If you return an async block from an event handler, dioxus will automatically spawn it:
use dioxus::prelude::*;
fn App() -> Element {
rsx! {
button {
// The `onclick` event can also accept a closure that returns an async block
onclick: move |_| async move {
tokio::time::sleep(std::time::Duration::from_secs(1)).await;
println!("You clicked the button one second ago!");
},
"Click me"
}
}
}§Compiler errors you may run into while using event handlers
function requires argument type to outlive `'static`
Event handler in Dioxus need only access data that can last for the entire lifetime of the application. That generally means data that is moved into the closure. If you get this error, you may have forgotten to add move to your closure.
Broken component:
// We return an Element which can last as long as the component is on the screen
fn App() -> Element {
// Signals are `Copy` which makes them very easy to move into `'static` closures like event handlers
let state = use_signal(|| "hello world".to_string());
rsx! {
button {
// ❌ Without `move`, rust will try to borrow the `state` signal which fails because the state signal is dropped at the end of the function
onclick: |_| {
println!("You clicked the button! The state is: {state}");
},
"Click me"
}
}
// The state signal is dropped here, but the event handler still needs to access it
}Fixed component:
fn App() -> Element {
let state = use_signal(|| "hello world".to_string());
rsx! {
button {
// ✅ The `move` keyword tells rust it can move the `state` signal into the closure. Since the closure owns the signal state, it can read it even after the function returns
onclick: move |_| {
println!("You clicked the button! The state is: {state}");
},
"Click me"
}
}
}use of moved value: `your_value` value used here after move
Data in rust has a single owner. If you run into this error, you have likely tried to move data that isn’t Copy into two different closures. You can fix this issue by making your data Copy or calling clone on it before you move it into the closure.
Broken component:
// `MyComponent` accepts a string which cannot be copied implicitly
#[component]
fn MyComponent(string: String) -> Element {
rsx! {
button {
// ❌ We are moving the string into the onclick handler which means we can't access it elsewhere
onclick: move |_| {
println!("{string}");
},
"Print hello world"
}
button {
// ❌ Since we already moved the string, we can't move it into the onclick handler again. This will cause a compiler error
onclick: move |_| {
println!("{string}");
},
"Print hello world again"
}
}
}You can fix this issue by either:
- Making your data
CopywithReadSignal:
// `MyComponent` accepts `ReadSignal<String>` which implements `Copy`
#[component]
fn MyComponent(string: ReadSignal<String>) -> Element {
rsx! {
button {
// ✅ Because the `string` signal is `Copy`, we can copy it into the closure while still having access to it elsewhere
onclick: move |_| println!("{}", string),
"Print hello world"
}
button {
// ✅ Since `string` is `Copy`, we can move it into the onclick handler again
onclick: move |_| println!("{}", string),
"Print hello world again"
}
}
}- Calling
cloneon your data before you move it into the closure:
// `MyComponent` accepts a string which doesn't implement `Copy`
#[component]
fn MyComponent(string: String) -> Element {
rsx! {
button {
// ✅ The string only has one owner. We could move it into this closure, but since we want to use the string in other closures later, we will clone it instead
onclick: {
// Clone the string in a new block
let string = string.clone();
// Then move the cloned string into the closure
move |_| println!("{}", string)
},
"Print hello world"
}
button {
// ✅ We don't use the string after this closure, so we can just move it into the closure directly
onclick: move |_| println!("{}", string),
"Print hello world again"
}
}
}Sourcefn onvolumechange<__Marker>(
self,
event_handler: impl EventHandlerValue<MediaData, __Marker>,
) -> <Self as AttributeBuilderTarget>::Output
fn onvolumechange<__Marker>( self, event_handler: impl EventHandlerValue<MediaData, __Marker>, ) -> <Self as AttributeBuilderTarget>::Output
onvolumechange
General Event Handler Information
§Event Handlers
Event Handlers let you react to user input in your application. In Dioxus, event handlers accept a closure that is called when the event occurs:
use dioxus::prelude::*;
fn App() -> Element {
rsx! {
button {
// The `onclick` event accepts a closure with the signature `fn(Event)`
onclick: |event_data| println!("clicked! I got the event data: {event_data:?}"),
"Click me"
}
}
}§Event Lifetimes
Events take a closure with the 'static lifetime. This means that the closure can only access data that either exists for the entire lifetime of the application, or data that you move into the closure.
State in dioxus is copy which makes it very easy to move into 'static closures like event handlers:
let mut count = use_signal(|| 0);
rsx! {
button {
// Since we added the `move` keyword, the closure will move the `count` signal into the closure
onclick: move |_| {
// This will panic because the `count` signal is not in scope
count.set(count() + 1);
},
"Click me"
}
};If you need to access data that is not Copy, you may need to clone the data before you move it into the closure:
// String is not `Copy`
let string = "hello world".to_string();
rsx! {
button {
// The string only has one owner. We could move it into this closure, but since we want to use the string in other closures later, we will clone it instead
onclick: {
// Clone the string in a new block
let string = string.clone();
// Then move the cloned string into the closure
move |_| println!("{}", string)
},
"Print hello world"
}
button {
// We don't use the string after this closure, so we can just move it into the closure directly
onclick: move |_| println!("{}", string),
"Print hello world again"
}
};§Async Event Handlers
In addition to closures that return nothing, you can also use async closures to handle events. If you return an async block from an event handler, dioxus will automatically spawn it:
use dioxus::prelude::*;
fn App() -> Element {
rsx! {
button {
// The `onclick` event can also accept a closure that returns an async block
onclick: move |_| async move {
tokio::time::sleep(std::time::Duration::from_secs(1)).await;
println!("You clicked the button one second ago!");
},
"Click me"
}
}
}§Compiler errors you may run into while using event handlers
function requires argument type to outlive `'static`
Event handler in Dioxus need only access data that can last for the entire lifetime of the application. That generally means data that is moved into the closure. If you get this error, you may have forgotten to add move to your closure.
Broken component:
// We return an Element which can last as long as the component is on the screen
fn App() -> Element {
// Signals are `Copy` which makes them very easy to move into `'static` closures like event handlers
let state = use_signal(|| "hello world".to_string());
rsx! {
button {
// ❌ Without `move`, rust will try to borrow the `state` signal which fails because the state signal is dropped at the end of the function
onclick: |_| {
println!("You clicked the button! The state is: {state}");
},
"Click me"
}
}
// The state signal is dropped here, but the event handler still needs to access it
}Fixed component:
fn App() -> Element {
let state = use_signal(|| "hello world".to_string());
rsx! {
button {
// ✅ The `move` keyword tells rust it can move the `state` signal into the closure. Since the closure owns the signal state, it can read it even after the function returns
onclick: move |_| {
println!("You clicked the button! The state is: {state}");
},
"Click me"
}
}
}use of moved value: `your_value` value used here after move
Data in rust has a single owner. If you run into this error, you have likely tried to move data that isn’t Copy into two different closures. You can fix this issue by making your data Copy or calling clone on it before you move it into the closure.
Broken component:
// `MyComponent` accepts a string which cannot be copied implicitly
#[component]
fn MyComponent(string: String) -> Element {
rsx! {
button {
// ❌ We are moving the string into the onclick handler which means we can't access it elsewhere
onclick: move |_| {
println!("{string}");
},
"Print hello world"
}
button {
// ❌ Since we already moved the string, we can't move it into the onclick handler again. This will cause a compiler error
onclick: move |_| {
println!("{string}");
},
"Print hello world again"
}
}
}You can fix this issue by either:
- Making your data
CopywithReadSignal:
// `MyComponent` accepts `ReadSignal<String>` which implements `Copy`
#[component]
fn MyComponent(string: ReadSignal<String>) -> Element {
rsx! {
button {
// ✅ Because the `string` signal is `Copy`, we can copy it into the closure while still having access to it elsewhere
onclick: move |_| println!("{}", string),
"Print hello world"
}
button {
// ✅ Since `string` is `Copy`, we can move it into the onclick handler again
onclick: move |_| println!("{}", string),
"Print hello world again"
}
}
}- Calling
cloneon your data before you move it into the closure:
// `MyComponent` accepts a string which doesn't implement `Copy`
#[component]
fn MyComponent(string: String) -> Element {
rsx! {
button {
// ✅ The string only has one owner. We could move it into this closure, but since we want to use the string in other closures later, we will clone it instead
onclick: {
// Clone the string in a new block
let string = string.clone();
// Then move the cloned string into the closure
move |_| println!("{}", string)
},
"Print hello world"
}
button {
// ✅ We don't use the string after this closure, so we can just move it into the closure directly
onclick: move |_| println!("{}", string),
"Print hello world again"
}
}
}Sourcefn onwaiting<__Marker>(
self,
event_handler: impl EventHandlerValue<MediaData, __Marker>,
) -> <Self as AttributeBuilderTarget>::Output
fn onwaiting<__Marker>( self, event_handler: impl EventHandlerValue<MediaData, __Marker>, ) -> <Self as AttributeBuilderTarget>::Output
onwaiting
General Event Handler Information
§Event Handlers
Event Handlers let you react to user input in your application. In Dioxus, event handlers accept a closure that is called when the event occurs:
use dioxus::prelude::*;
fn App() -> Element {
rsx! {
button {
// The `onclick` event accepts a closure with the signature `fn(Event)`
onclick: |event_data| println!("clicked! I got the event data: {event_data:?}"),
"Click me"
}
}
}§Event Lifetimes
Events take a closure with the 'static lifetime. This means that the closure can only access data that either exists for the entire lifetime of the application, or data that you move into the closure.
State in dioxus is copy which makes it very easy to move into 'static closures like event handlers:
let mut count = use_signal(|| 0);
rsx! {
button {
// Since we added the `move` keyword, the closure will move the `count` signal into the closure
onclick: move |_| {
// This will panic because the `count` signal is not in scope
count.set(count() + 1);
},
"Click me"
}
};If you need to access data that is not Copy, you may need to clone the data before you move it into the closure:
// String is not `Copy`
let string = "hello world".to_string();
rsx! {
button {
// The string only has one owner. We could move it into this closure, but since we want to use the string in other closures later, we will clone it instead
onclick: {
// Clone the string in a new block
let string = string.clone();
// Then move the cloned string into the closure
move |_| println!("{}", string)
},
"Print hello world"
}
button {
// We don't use the string after this closure, so we can just move it into the closure directly
onclick: move |_| println!("{}", string),
"Print hello world again"
}
};§Async Event Handlers
In addition to closures that return nothing, you can also use async closures to handle events. If you return an async block from an event handler, dioxus will automatically spawn it:
use dioxus::prelude::*;
fn App() -> Element {
rsx! {
button {
// The `onclick` event can also accept a closure that returns an async block
onclick: move |_| async move {
tokio::time::sleep(std::time::Duration::from_secs(1)).await;
println!("You clicked the button one second ago!");
},
"Click me"
}
}
}§Compiler errors you may run into while using event handlers
function requires argument type to outlive `'static`
Event handler in Dioxus need only access data that can last for the entire lifetime of the application. That generally means data that is moved into the closure. If you get this error, you may have forgotten to add move to your closure.
Broken component:
// We return an Element which can last as long as the component is on the screen
fn App() -> Element {
// Signals are `Copy` which makes them very easy to move into `'static` closures like event handlers
let state = use_signal(|| "hello world".to_string());
rsx! {
button {
// ❌ Without `move`, rust will try to borrow the `state` signal which fails because the state signal is dropped at the end of the function
onclick: |_| {
println!("You clicked the button! The state is: {state}");
},
"Click me"
}
}
// The state signal is dropped here, but the event handler still needs to access it
}Fixed component:
fn App() -> Element {
let state = use_signal(|| "hello world".to_string());
rsx! {
button {
// ✅ The `move` keyword tells rust it can move the `state` signal into the closure. Since the closure owns the signal state, it can read it even after the function returns
onclick: move |_| {
println!("You clicked the button! The state is: {state}");
},
"Click me"
}
}
}use of moved value: `your_value` value used here after move
Data in rust has a single owner. If you run into this error, you have likely tried to move data that isn’t Copy into two different closures. You can fix this issue by making your data Copy or calling clone on it before you move it into the closure.
Broken component:
// `MyComponent` accepts a string which cannot be copied implicitly
#[component]
fn MyComponent(string: String) -> Element {
rsx! {
button {
// ❌ We are moving the string into the onclick handler which means we can't access it elsewhere
onclick: move |_| {
println!("{string}");
},
"Print hello world"
}
button {
// ❌ Since we already moved the string, we can't move it into the onclick handler again. This will cause a compiler error
onclick: move |_| {
println!("{string}");
},
"Print hello world again"
}
}
}You can fix this issue by either:
- Making your data
CopywithReadSignal:
// `MyComponent` accepts `ReadSignal<String>` which implements `Copy`
#[component]
fn MyComponent(string: ReadSignal<String>) -> Element {
rsx! {
button {
// ✅ Because the `string` signal is `Copy`, we can copy it into the closure while still having access to it elsewhere
onclick: move |_| println!("{}", string),
"Print hello world"
}
button {
// ✅ Since `string` is `Copy`, we can move it into the onclick handler again
onclick: move |_| println!("{}", string),
"Print hello world again"
}
}
}- Calling
cloneon your data before you move it into the closure:
// `MyComponent` accepts a string which doesn't implement `Copy`
#[component]
fn MyComponent(string: String) -> Element {
rsx! {
button {
// ✅ The string only has one owner. We could move it into this closure, but since we want to use the string in other closures later, we will clone it instead
onclick: {
// Clone the string in a new block
let string = string.clone();
// Then move the cloned string into the closure
move |_| println!("{}", string)
},
"Print hello world"
}
button {
// ✅ We don't use the string after this closure, so we can just move it into the closure directly
onclick: move |_| println!("{}", string),
"Print hello world again"
}
}
}Sourcefn onmounted<__Marker>(
self,
event_handler: impl EventHandlerValue<MountedData, __Marker>,
) -> <Self as AttributeBuilderTarget>::Output
fn onmounted<__Marker>( self, event_handler: impl EventHandlerValue<MountedData, __Marker>, ) -> <Self as AttributeBuilderTarget>::Output
onmounted
The onmounted event is fired when the element is first added to the DOM. This event gives you a MountedData object and lets you interact with the raw DOM element.
This event is fired once per element. If you need to access the element multiple times, you can store the MountedData object in a use_signal hook and use it as needed.
§Examples
fn App() -> Element {
let mut header_element = use_signal(|| None);
rsx! {
div {
h1 {
// The onmounted event will run the first time the h1 element is mounted
onmounted: move |element| header_element.set(Some(element.data())),
"Scroll to top example"
}
for i in 0..100 {
div { "Item {i}" }
}
button {
// When you click the button, if the header element has been mounted, we scroll to that element
onclick: move |_| async move {
if let Some(header) = header_element.cloned() {
let _ = header.scroll_to(ScrollBehavior::Smooth).await;
}
},
"Scroll to top"
}
}
}
}The MountedData struct contains cross platform APIs that work on the desktop, mobile, liveview and web platforms. For the web platform, you can also downcast the MountedData event to the web-sys::Element type for more web specific APIs:
use dioxus::prelude::*;
use dioxus_web::WebEventExt; // provides [`as_web_event()`] method
fn App() -> Element {
rsx! {
div {
id: "some-id",
onmounted: move |element| {
// You can use the web_event trait to downcast the element to a web specific event. For the mounted event, this will be a web_sys::Element
let web_sys_element = element.as_web_event();
assert_eq!(web_sys_element.id(), "some-id");
}
}
}
}General Event Handler Information
§Event Handlers
Event Handlers let you react to user input in your application. In Dioxus, event handlers accept a closure that is called when the event occurs:
use dioxus::prelude::*;
fn App() -> Element {
rsx! {
button {
// The `onclick` event accepts a closure with the signature `fn(Event)`
onclick: |event_data| println!("clicked! I got the event data: {event_data:?}"),
"Click me"
}
}
}§Event Lifetimes
Events take a closure with the 'static lifetime. This means that the closure can only access data that either exists for the entire lifetime of the application, or data that you move into the closure.
State in dioxus is copy which makes it very easy to move into 'static closures like event handlers:
let mut count = use_signal(|| 0);
rsx! {
button {
// Since we added the `move` keyword, the closure will move the `count` signal into the closure
onclick: move |_| {
// This will panic because the `count` signal is not in scope
count.set(count() + 1);
},
"Click me"
}
};If you need to access data that is not Copy, you may need to clone the data before you move it into the closure:
// String is not `Copy`
let string = "hello world".to_string();
rsx! {
button {
// The string only has one owner. We could move it into this closure, but since we want to use the string in other closures later, we will clone it instead
onclick: {
// Clone the string in a new block
let string = string.clone();
// Then move the cloned string into the closure
move |_| println!("{}", string)
},
"Print hello world"
}
button {
// We don't use the string after this closure, so we can just move it into the closure directly
onclick: move |_| println!("{}", string),
"Print hello world again"
}
};§Async Event Handlers
In addition to closures that return nothing, you can also use async closures to handle events. If you return an async block from an event handler, dioxus will automatically spawn it:
use dioxus::prelude::*;
fn App() -> Element {
rsx! {
button {
// The `onclick` event can also accept a closure that returns an async block
onclick: move |_| async move {
tokio::time::sleep(std::time::Duration::from_secs(1)).await;
println!("You clicked the button one second ago!");
},
"Click me"
}
}
}§Compiler errors you may run into while using event handlers
function requires argument type to outlive `'static`
Event handler in Dioxus need only access data that can last for the entire lifetime of the application. That generally means data that is moved into the closure. If you get this error, you may have forgotten to add move to your closure.
Broken component:
// We return an Element which can last as long as the component is on the screen
fn App() -> Element {
// Signals are `Copy` which makes them very easy to move into `'static` closures like event handlers
let state = use_signal(|| "hello world".to_string());
rsx! {
button {
// ❌ Without `move`, rust will try to borrow the `state` signal which fails because the state signal is dropped at the end of the function
onclick: |_| {
println!("You clicked the button! The state is: {state}");
},
"Click me"
}
}
// The state signal is dropped here, but the event handler still needs to access it
}Fixed component:
fn App() -> Element {
let state = use_signal(|| "hello world".to_string());
rsx! {
button {
// ✅ The `move` keyword tells rust it can move the `state` signal into the closure. Since the closure owns the signal state, it can read it even after the function returns
onclick: move |_| {
println!("You clicked the button! The state is: {state}");
},
"Click me"
}
}
}use of moved value: `your_value` value used here after move
Data in rust has a single owner. If you run into this error, you have likely tried to move data that isn’t Copy into two different closures. You can fix this issue by making your data Copy or calling clone on it before you move it into the closure.
Broken component:
// `MyComponent` accepts a string which cannot be copied implicitly
#[component]
fn MyComponent(string: String) -> Element {
rsx! {
button {
// ❌ We are moving the string into the onclick handler which means we can't access it elsewhere
onclick: move |_| {
println!("{string}");
},
"Print hello world"
}
button {
// ❌ Since we already moved the string, we can't move it into the onclick handler again. This will cause a compiler error
onclick: move |_| {
println!("{string}");
},
"Print hello world again"
}
}
}You can fix this issue by either:
- Making your data
CopywithReadSignal:
// `MyComponent` accepts `ReadSignal<String>` which implements `Copy`
#[component]
fn MyComponent(string: ReadSignal<String>) -> Element {
rsx! {
button {
// ✅ Because the `string` signal is `Copy`, we can copy it into the closure while still having access to it elsewhere
onclick: move |_| println!("{}", string),
"Print hello world"
}
button {
// ✅ Since `string` is `Copy`, we can move it into the onclick handler again
onclick: move |_| println!("{}", string),
"Print hello world again"
}
}
}- Calling
cloneon your data before you move it into the closure:
// `MyComponent` accepts a string which doesn't implement `Copy`
#[component]
fn MyComponent(string: String) -> Element {
rsx! {
button {
// ✅ The string only has one owner. We could move it into this closure, but since we want to use the string in other closures later, we will clone it instead
onclick: {
// Clone the string in a new block
let string = string.clone();
// Then move the cloned string into the closure
move |_| println!("{}", string)
},
"Print hello world"
}
button {
// ✅ We don't use the string after this closure, so we can just move it into the closure directly
onclick: move |_| println!("{}", string),
"Print hello world again"
}
}
}Sourcefn onclick<__Marker>(
self,
event_handler: impl EventHandlerValue<MouseData, __Marker>,
) -> <Self as AttributeBuilderTarget>::Output
fn onclick<__Marker>( self, event_handler: impl EventHandlerValue<MouseData, __Marker>, ) -> <Self as AttributeBuilderTarget>::Output
onclick Execute a callback when a button is clicked.
§Description
An element receives a click event when a pointing device button (such as a mouse’s primary mouse button) is both pressed and released while the pointer is located inside the element.
- Bubbles: Yes
- Cancelable: Yes
- Interface(InteData):
MouseEvent
If the button is pressed on one element and the pointer is moved outside the element before the button
is released, the event is fired on the most specific ancestor element that contained both elements.
click fires after both the mousedown and mouseup events have fired, in that order.
§Example
rsx!( button { onclick: move |_| tracing::info!("Clicked!"), "click me" } )§Reference
- https://www.w3schools.com/tags/ev_onclick.asp
- https://developer.mozilla.org/en-US/docs/Web/API/Element/click_event
General Event Handler Information
§Event Handlers
Event Handlers let you react to user input in your application. In Dioxus, event handlers accept a closure that is called when the event occurs:
use dioxus::prelude::*;
fn App() -> Element {
rsx! {
button {
// The `onclick` event accepts a closure with the signature `fn(Event)`
onclick: |event_data| println!("clicked! I got the event data: {event_data:?}"),
"Click me"
}
}
}§Event Lifetimes
Events take a closure with the 'static lifetime. This means that the closure can only access data that either exists for the entire lifetime of the application, or data that you move into the closure.
State in dioxus is copy which makes it very easy to move into 'static closures like event handlers:
let mut count = use_signal(|| 0);
rsx! {
button {
// Since we added the `move` keyword, the closure will move the `count` signal into the closure
onclick: move |_| {
// This will panic because the `count` signal is not in scope
count.set(count() + 1);
},
"Click me"
}
};If you need to access data that is not Copy, you may need to clone the data before you move it into the closure:
// String is not `Copy`
let string = "hello world".to_string();
rsx! {
button {
// The string only has one owner. We could move it into this closure, but since we want to use the string in other closures later, we will clone it instead
onclick: {
// Clone the string in a new block
let string = string.clone();
// Then move the cloned string into the closure
move |_| println!("{}", string)
},
"Print hello world"
}
button {
// We don't use the string after this closure, so we can just move it into the closure directly
onclick: move |_| println!("{}", string),
"Print hello world again"
}
};§Async Event Handlers
In addition to closures that return nothing, you can also use async closures to handle events. If you return an async block from an event handler, dioxus will automatically spawn it:
use dioxus::prelude::*;
fn App() -> Element {
rsx! {
button {
// The `onclick` event can also accept a closure that returns an async block
onclick: move |_| async move {
tokio::time::sleep(std::time::Duration::from_secs(1)).await;
println!("You clicked the button one second ago!");
},
"Click me"
}
}
}§Compiler errors you may run into while using event handlers
function requires argument type to outlive `'static`
Event handler in Dioxus need only access data that can last for the entire lifetime of the application. That generally means data that is moved into the closure. If you get this error, you may have forgotten to add move to your closure.
Broken component:
// We return an Element which can last as long as the component is on the screen
fn App() -> Element {
// Signals are `Copy` which makes them very easy to move into `'static` closures like event handlers
let state = use_signal(|| "hello world".to_string());
rsx! {
button {
// ❌ Without `move`, rust will try to borrow the `state` signal which fails because the state signal is dropped at the end of the function
onclick: |_| {
println!("You clicked the button! The state is: {state}");
},
"Click me"
}
}
// The state signal is dropped here, but the event handler still needs to access it
}Fixed component:
fn App() -> Element {
let state = use_signal(|| "hello world".to_string());
rsx! {
button {
// ✅ The `move` keyword tells rust it can move the `state` signal into the closure. Since the closure owns the signal state, it can read it even after the function returns
onclick: move |_| {
println!("You clicked the button! The state is: {state}");
},
"Click me"
}
}
}use of moved value: `your_value` value used here after move
Data in rust has a single owner. If you run into this error, you have likely tried to move data that isn’t Copy into two different closures. You can fix this issue by making your data Copy or calling clone on it before you move it into the closure.
Broken component:
// `MyComponent` accepts a string which cannot be copied implicitly
#[component]
fn MyComponent(string: String) -> Element {
rsx! {
button {
// ❌ We are moving the string into the onclick handler which means we can't access it elsewhere
onclick: move |_| {
println!("{string}");
},
"Print hello world"
}
button {
// ❌ Since we already moved the string, we can't move it into the onclick handler again. This will cause a compiler error
onclick: move |_| {
println!("{string}");
},
"Print hello world again"
}
}
}You can fix this issue by either:
- Making your data
CopywithReadSignal:
// `MyComponent` accepts `ReadSignal<String>` which implements `Copy`
#[component]
fn MyComponent(string: ReadSignal<String>) -> Element {
rsx! {
button {
// ✅ Because the `string` signal is `Copy`, we can copy it into the closure while still having access to it elsewhere
onclick: move |_| println!("{}", string),
"Print hello world"
}
button {
// ✅ Since `string` is `Copy`, we can move it into the onclick handler again
onclick: move |_| println!("{}", string),
"Print hello world again"
}
}
}- Calling
cloneon your data before you move it into the closure:
// `MyComponent` accepts a string which doesn't implement `Copy`
#[component]
fn MyComponent(string: String) -> Element {
rsx! {
button {
// ✅ The string only has one owner. We could move it into this closure, but since we want to use the string in other closures later, we will clone it instead
onclick: {
// Clone the string in a new block
let string = string.clone();
// Then move the cloned string into the closure
move |_| println!("{}", string)
},
"Print hello world"
}
button {
// ✅ We don't use the string after this closure, so we can just move it into the closure directly
onclick: move |_| println!("{}", string),
"Print hello world again"
}
}
}oncontextmenu
General Event Handler Information
§Event Handlers
Event Handlers let you react to user input in your application. In Dioxus, event handlers accept a closure that is called when the event occurs:
use dioxus::prelude::*;
fn App() -> Element {
rsx! {
button {
// The `onclick` event accepts a closure with the signature `fn(Event)`
onclick: |event_data| println!("clicked! I got the event data: {event_data:?}"),
"Click me"
}
}
}§Event Lifetimes
Events take a closure with the 'static lifetime. This means that the closure can only access data that either exists for the entire lifetime of the application, or data that you move into the closure.
State in dioxus is copy which makes it very easy to move into 'static closures like event handlers:
let mut count = use_signal(|| 0);
rsx! {
button {
// Since we added the `move` keyword, the closure will move the `count` signal into the closure
onclick: move |_| {
// This will panic because the `count` signal is not in scope
count.set(count() + 1);
},
"Click me"
}
};If you need to access data that is not Copy, you may need to clone the data before you move it into the closure:
// String is not `Copy`
let string = "hello world".to_string();
rsx! {
button {
// The string only has one owner. We could move it into this closure, but since we want to use the string in other closures later, we will clone it instead
onclick: {
// Clone the string in a new block
let string = string.clone();
// Then move the cloned string into the closure
move |_| println!("{}", string)
},
"Print hello world"
}
button {
// We don't use the string after this closure, so we can just move it into the closure directly
onclick: move |_| println!("{}", string),
"Print hello world again"
}
};§Async Event Handlers
In addition to closures that return nothing, you can also use async closures to handle events. If you return an async block from an event handler, dioxus will automatically spawn it:
use dioxus::prelude::*;
fn App() -> Element {
rsx! {
button {
// The `onclick` event can also accept a closure that returns an async block
onclick: move |_| async move {
tokio::time::sleep(std::time::Duration::from_secs(1)).await;
println!("You clicked the button one second ago!");
},
"Click me"
}
}
}§Compiler errors you may run into while using event handlers
function requires argument type to outlive `'static`
Event handler in Dioxus need only access data that can last for the entire lifetime of the application. That generally means data that is moved into the closure. If you get this error, you may have forgotten to add move to your closure.
Broken component:
// We return an Element which can last as long as the component is on the screen
fn App() -> Element {
// Signals are `Copy` which makes them very easy to move into `'static` closures like event handlers
let state = use_signal(|| "hello world".to_string());
rsx! {
button {
// ❌ Without `move`, rust will try to borrow the `state` signal which fails because the state signal is dropped at the end of the function
onclick: |_| {
println!("You clicked the button! The state is: {state}");
},
"Click me"
}
}
// The state signal is dropped here, but the event handler still needs to access it
}Fixed component:
fn App() -> Element {
let state = use_signal(|| "hello world".to_string());
rsx! {
button {
// ✅ The `move` keyword tells rust it can move the `state` signal into the closure. Since the closure owns the signal state, it can read it even after the function returns
onclick: move |_| {
println!("You clicked the button! The state is: {state}");
},
"Click me"
}
}
}use of moved value: `your_value` value used here after move
Data in rust has a single owner. If you run into this error, you have likely tried to move data that isn’t Copy into two different closures. You can fix this issue by making your data Copy or calling clone on it before you move it into the closure.
Broken component:
// `MyComponent` accepts a string which cannot be copied implicitly
#[component]
fn MyComponent(string: String) -> Element {
rsx! {
button {
// ❌ We are moving the string into the onclick handler which means we can't access it elsewhere
onclick: move |_| {
println!("{string}");
},
"Print hello world"
}
button {
// ❌ Since we already moved the string, we can't move it into the onclick handler again. This will cause a compiler error
onclick: move |_| {
println!("{string}");
},
"Print hello world again"
}
}
}You can fix this issue by either:
- Making your data
CopywithReadSignal:
// `MyComponent` accepts `ReadSignal<String>` which implements `Copy`
#[component]
fn MyComponent(string: ReadSignal<String>) -> Element {
rsx! {
button {
// ✅ Because the `string` signal is `Copy`, we can copy it into the closure while still having access to it elsewhere
onclick: move |_| println!("{}", string),
"Print hello world"
}
button {
// ✅ Since `string` is `Copy`, we can move it into the onclick handler again
onclick: move |_| println!("{}", string),
"Print hello world again"
}
}
}- Calling
cloneon your data before you move it into the closure:
// `MyComponent` accepts a string which doesn't implement `Copy`
#[component]
fn MyComponent(string: String) -> Element {
rsx! {
button {
// ✅ The string only has one owner. We could move it into this closure, but since we want to use the string in other closures later, we will clone it instead
onclick: {
// Clone the string in a new block
let string = string.clone();
// Then move the cloned string into the closure
move |_| println!("{}", string)
},
"Print hello world"
}
button {
// ✅ We don't use the string after this closure, so we can just move it into the closure directly
onclick: move |_| println!("{}", string),
"Print hello world again"
}
}
}Sourcefn ondblclick<__Marker>(
self,
event_handler: impl EventHandlerValue<MouseData, __Marker>,
) -> <Self as AttributeBuilderTarget>::Output
👎Deprecated since 0.5.0: use ondoubleclick instead
fn ondblclick<__Marker>( self, event_handler: impl EventHandlerValue<MouseData, __Marker>, ) -> <Self as AttributeBuilderTarget>::Output
use ondoubleclick instead
ondblclick
General Event Handler Information
§Event Handlers
Event Handlers let you react to user input in your application. In Dioxus, event handlers accept a closure that is called when the event occurs:
use dioxus::prelude::*;
fn App() -> Element {
rsx! {
button {
// The `onclick` event accepts a closure with the signature `fn(Event)`
onclick: |event_data| println!("clicked! I got the event data: {event_data:?}"),
"Click me"
}
}
}§Event Lifetimes
Events take a closure with the 'static lifetime. This means that the closure can only access data that either exists for the entire lifetime of the application, or data that you move into the closure.
State in dioxus is copy which makes it very easy to move into 'static closures like event handlers:
let mut count = use_signal(|| 0);
rsx! {
button {
// Since we added the `move` keyword, the closure will move the `count` signal into the closure
onclick: move |_| {
// This will panic because the `count` signal is not in scope
count.set(count() + 1);
},
"Click me"
}
};If you need to access data that is not Copy, you may need to clone the data before you move it into the closure:
// String is not `Copy`
let string = "hello world".to_string();
rsx! {
button {
// The string only has one owner. We could move it into this closure, but since we want to use the string in other closures later, we will clone it instead
onclick: {
// Clone the string in a new block
let string = string.clone();
// Then move the cloned string into the closure
move |_| println!("{}", string)
},
"Print hello world"
}
button {
// We don't use the string after this closure, so we can just move it into the closure directly
onclick: move |_| println!("{}", string),
"Print hello world again"
}
};§Async Event Handlers
In addition to closures that return nothing, you can also use async closures to handle events. If you return an async block from an event handler, dioxus will automatically spawn it:
use dioxus::prelude::*;
fn App() -> Element {
rsx! {
button {
// The `onclick` event can also accept a closure that returns an async block
onclick: move |_| async move {
tokio::time::sleep(std::time::Duration::from_secs(1)).await;
println!("You clicked the button one second ago!");
},
"Click me"
}
}
}§Compiler errors you may run into while using event handlers
function requires argument type to outlive `'static`
Event handler in Dioxus need only access data that can last for the entire lifetime of the application. That generally means data that is moved into the closure. If you get this error, you may have forgotten to add move to your closure.
Broken component:
// We return an Element which can last as long as the component is on the screen
fn App() -> Element {
// Signals are `Copy` which makes them very easy to move into `'static` closures like event handlers
let state = use_signal(|| "hello world".to_string());
rsx! {
button {
// ❌ Without `move`, rust will try to borrow the `state` signal which fails because the state signal is dropped at the end of the function
onclick: |_| {
println!("You clicked the button! The state is: {state}");
},
"Click me"
}
}
// The state signal is dropped here, but the event handler still needs to access it
}Fixed component:
fn App() -> Element {
let state = use_signal(|| "hello world".to_string());
rsx! {
button {
// ✅ The `move` keyword tells rust it can move the `state` signal into the closure. Since the closure owns the signal state, it can read it even after the function returns
onclick: move |_| {
println!("You clicked the button! The state is: {state}");
},
"Click me"
}
}
}use of moved value: `your_value` value used here after move
Data in rust has a single owner. If you run into this error, you have likely tried to move data that isn’t Copy into two different closures. You can fix this issue by making your data Copy or calling clone on it before you move it into the closure.
Broken component:
// `MyComponent` accepts a string which cannot be copied implicitly
#[component]
fn MyComponent(string: String) -> Element {
rsx! {
button {
// ❌ We are moving the string into the onclick handler which means we can't access it elsewhere
onclick: move |_| {
println!("{string}");
},
"Print hello world"
}
button {
// ❌ Since we already moved the string, we can't move it into the onclick handler again. This will cause a compiler error
onclick: move |_| {
println!("{string}");
},
"Print hello world again"
}
}
}You can fix this issue by either:
- Making your data
CopywithReadSignal:
// `MyComponent` accepts `ReadSignal<String>` which implements `Copy`
#[component]
fn MyComponent(string: ReadSignal<String>) -> Element {
rsx! {
button {
// ✅ Because the `string` signal is `Copy`, we can copy it into the closure while still having access to it elsewhere
onclick: move |_| println!("{}", string),
"Print hello world"
}
button {
// ✅ Since `string` is `Copy`, we can move it into the onclick handler again
onclick: move |_| println!("{}", string),
"Print hello world again"
}
}
}- Calling
cloneon your data before you move it into the closure:
// `MyComponent` accepts a string which doesn't implement `Copy`
#[component]
fn MyComponent(string: String) -> Element {
rsx! {
button {
// ✅ The string only has one owner. We could move it into this closure, but since we want to use the string in other closures later, we will clone it instead
onclick: {
// Clone the string in a new block
let string = string.clone();
// Then move the cloned string into the closure
move |_| println!("{}", string)
},
"Print hello world"
}
button {
// ✅ We don't use the string after this closure, so we can just move it into the closure directly
onclick: move |_| println!("{}", string),
"Print hello world again"
}
}
}Sourcefn ondoubleclick<__Marker>(
self,
event_handler: impl EventHandlerValue<MouseData, __Marker>,
) -> <Self as AttributeBuilderTarget>::Output
fn ondoubleclick<__Marker>( self, event_handler: impl EventHandlerValue<MouseData, __Marker>, ) -> <Self as AttributeBuilderTarget>::Output
ondoubleclick
General Event Handler Information
§Event Handlers
Event Handlers let you react to user input in your application. In Dioxus, event handlers accept a closure that is called when the event occurs:
use dioxus::prelude::*;
fn App() -> Element {
rsx! {
button {
// The `onclick` event accepts a closure with the signature `fn(Event)`
onclick: |event_data| println!("clicked! I got the event data: {event_data:?}"),
"Click me"
}
}
}§Event Lifetimes
Events take a closure with the 'static lifetime. This means that the closure can only access data that either exists for the entire lifetime of the application, or data that you move into the closure.
State in dioxus is copy which makes it very easy to move into 'static closures like event handlers:
let mut count = use_signal(|| 0);
rsx! {
button {
// Since we added the `move` keyword, the closure will move the `count` signal into the closure
onclick: move |_| {
// This will panic because the `count` signal is not in scope
count.set(count() + 1);
},
"Click me"
}
};If you need to access data that is not Copy, you may need to clone the data before you move it into the closure:
// String is not `Copy`
let string = "hello world".to_string();
rsx! {
button {
// The string only has one owner. We could move it into this closure, but since we want to use the string in other closures later, we will clone it instead
onclick: {
// Clone the string in a new block
let string = string.clone();
// Then move the cloned string into the closure
move |_| println!("{}", string)
},
"Print hello world"
}
button {
// We don't use the string after this closure, so we can just move it into the closure directly
onclick: move |_| println!("{}", string),
"Print hello world again"
}
};§Async Event Handlers
In addition to closures that return nothing, you can also use async closures to handle events. If you return an async block from an event handler, dioxus will automatically spawn it:
use dioxus::prelude::*;
fn App() -> Element {
rsx! {
button {
// The `onclick` event can also accept a closure that returns an async block
onclick: move |_| async move {
tokio::time::sleep(std::time::Duration::from_secs(1)).await;
println!("You clicked the button one second ago!");
},
"Click me"
}
}
}§Compiler errors you may run into while using event handlers
function requires argument type to outlive `'static`
Event handler in Dioxus need only access data that can last for the entire lifetime of the application. That generally means data that is moved into the closure. If you get this error, you may have forgotten to add move to your closure.
Broken component:
// We return an Element which can last as long as the component is on the screen
fn App() -> Element {
// Signals are `Copy` which makes them very easy to move into `'static` closures like event handlers
let state = use_signal(|| "hello world".to_string());
rsx! {
button {
// ❌ Without `move`, rust will try to borrow the `state` signal which fails because the state signal is dropped at the end of the function
onclick: |_| {
println!("You clicked the button! The state is: {state}");
},
"Click me"
}
}
// The state signal is dropped here, but the event handler still needs to access it
}Fixed component:
fn App() -> Element {
let state = use_signal(|| "hello world".to_string());
rsx! {
button {
// ✅ The `move` keyword tells rust it can move the `state` signal into the closure. Since the closure owns the signal state, it can read it even after the function returns
onclick: move |_| {
println!("You clicked the button! The state is: {state}");
},
"Click me"
}
}
}use of moved value: `your_value` value used here after move
Data in rust has a single owner. If you run into this error, you have likely tried to move data that isn’t Copy into two different closures. You can fix this issue by making your data Copy or calling clone on it before you move it into the closure.
Broken component:
// `MyComponent` accepts a string which cannot be copied implicitly
#[component]
fn MyComponent(string: String) -> Element {
rsx! {
button {
// ❌ We are moving the string into the onclick handler which means we can't access it elsewhere
onclick: move |_| {
println!("{string}");
},
"Print hello world"
}
button {
// ❌ Since we already moved the string, we can't move it into the onclick handler again. This will cause a compiler error
onclick: move |_| {
println!("{string}");
},
"Print hello world again"
}
}
}You can fix this issue by either:
- Making your data
CopywithReadSignal:
// `MyComponent` accepts `ReadSignal<String>` which implements `Copy`
#[component]
fn MyComponent(string: ReadSignal<String>) -> Element {
rsx! {
button {
// ✅ Because the `string` signal is `Copy`, we can copy it into the closure while still having access to it elsewhere
onclick: move |_| println!("{}", string),
"Print hello world"
}
button {
// ✅ Since `string` is `Copy`, we can move it into the onclick handler again
onclick: move |_| println!("{}", string),
"Print hello world again"
}
}
}- Calling
cloneon your data before you move it into the closure:
// `MyComponent` accepts a string which doesn't implement `Copy`
#[component]
fn MyComponent(string: String) -> Element {
rsx! {
button {
// ✅ The string only has one owner. We could move it into this closure, but since we want to use the string in other closures later, we will clone it instead
onclick: {
// Clone the string in a new block
let string = string.clone();
// Then move the cloned string into the closure
move |_| println!("{}", string)
},
"Print hello world"
}
button {
// ✅ We don't use the string after this closure, so we can just move it into the closure directly
onclick: move |_| println!("{}", string),
"Print hello world again"
}
}
}Sourcefn onmousedown<__Marker>(
self,
event_handler: impl EventHandlerValue<MouseData, __Marker>,
) -> <Self as AttributeBuilderTarget>::Output
fn onmousedown<__Marker>( self, event_handler: impl EventHandlerValue<MouseData, __Marker>, ) -> <Self as AttributeBuilderTarget>::Output
onmousedown
General Event Handler Information
§Event Handlers
Event Handlers let you react to user input in your application. In Dioxus, event handlers accept a closure that is called when the event occurs:
use dioxus::prelude::*;
fn App() -> Element {
rsx! {
button {
// The `onclick` event accepts a closure with the signature `fn(Event)`
onclick: |event_data| println!("clicked! I got the event data: {event_data:?}"),
"Click me"
}
}
}§Event Lifetimes
Events take a closure with the 'static lifetime. This means that the closure can only access data that either exists for the entire lifetime of the application, or data that you move into the closure.
State in dioxus is copy which makes it very easy to move into 'static closures like event handlers:
let mut count = use_signal(|| 0);
rsx! {
button {
// Since we added the `move` keyword, the closure will move the `count` signal into the closure
onclick: move |_| {
// This will panic because the `count` signal is not in scope
count.set(count() + 1);
},
"Click me"
}
};If you need to access data that is not Copy, you may need to clone the data before you move it into the closure:
// String is not `Copy`
let string = "hello world".to_string();
rsx! {
button {
// The string only has one owner. We could move it into this closure, but since we want to use the string in other closures later, we will clone it instead
onclick: {
// Clone the string in a new block
let string = string.clone();
// Then move the cloned string into the closure
move |_| println!("{}", string)
},
"Print hello world"
}
button {
// We don't use the string after this closure, so we can just move it into the closure directly
onclick: move |_| println!("{}", string),
"Print hello world again"
}
};§Async Event Handlers
In addition to closures that return nothing, you can also use async closures to handle events. If you return an async block from an event handler, dioxus will automatically spawn it:
use dioxus::prelude::*;
fn App() -> Element {
rsx! {
button {
// The `onclick` event can also accept a closure that returns an async block
onclick: move |_| async move {
tokio::time::sleep(std::time::Duration::from_secs(1)).await;
println!("You clicked the button one second ago!");
},
"Click me"
}
}
}§Compiler errors you may run into while using event handlers
function requires argument type to outlive `'static`
Event handler in Dioxus need only access data that can last for the entire lifetime of the application. That generally means data that is moved into the closure. If you get this error, you may have forgotten to add move to your closure.
Broken component:
// We return an Element which can last as long as the component is on the screen
fn App() -> Element {
// Signals are `Copy` which makes them very easy to move into `'static` closures like event handlers
let state = use_signal(|| "hello world".to_string());
rsx! {
button {
// ❌ Without `move`, rust will try to borrow the `state` signal which fails because the state signal is dropped at the end of the function
onclick: |_| {
println!("You clicked the button! The state is: {state}");
},
"Click me"
}
}
// The state signal is dropped here, but the event handler still needs to access it
}Fixed component:
fn App() -> Element {
let state = use_signal(|| "hello world".to_string());
rsx! {
button {
// ✅ The `move` keyword tells rust it can move the `state` signal into the closure. Since the closure owns the signal state, it can read it even after the function returns
onclick: move |_| {
println!("You clicked the button! The state is: {state}");
},
"Click me"
}
}
}use of moved value: `your_value` value used here after move
Data in rust has a single owner. If you run into this error, you have likely tried to move data that isn’t Copy into two different closures. You can fix this issue by making your data Copy or calling clone on it before you move it into the closure.
Broken component:
// `MyComponent` accepts a string which cannot be copied implicitly
#[component]
fn MyComponent(string: String) -> Element {
rsx! {
button {
// ❌ We are moving the string into the onclick handler which means we can't access it elsewhere
onclick: move |_| {
println!("{string}");
},
"Print hello world"
}
button {
// ❌ Since we already moved the string, we can't move it into the onclick handler again. This will cause a compiler error
onclick: move |_| {
println!("{string}");
},
"Print hello world again"
}
}
}You can fix this issue by either:
- Making your data
CopywithReadSignal:
// `MyComponent` accepts `ReadSignal<String>` which implements `Copy`
#[component]
fn MyComponent(string: ReadSignal<String>) -> Element {
rsx! {
button {
// ✅ Because the `string` signal is `Copy`, we can copy it into the closure while still having access to it elsewhere
onclick: move |_| println!("{}", string),
"Print hello world"
}
button {
// ✅ Since `string` is `Copy`, we can move it into the onclick handler again
onclick: move |_| println!("{}", string),
"Print hello world again"
}
}
}- Calling
cloneon your data before you move it into the closure:
// `MyComponent` accepts a string which doesn't implement `Copy`
#[component]
fn MyComponent(string: String) -> Element {
rsx! {
button {
// ✅ The string only has one owner. We could move it into this closure, but since we want to use the string in other closures later, we will clone it instead
onclick: {
// Clone the string in a new block
let string = string.clone();
// Then move the cloned string into the closure
move |_| println!("{}", string)
},
"Print hello world"
}
button {
// ✅ We don't use the string after this closure, so we can just move it into the closure directly
onclick: move |_| println!("{}", string),
"Print hello world again"
}
}
}Sourcefn onmouseenter<__Marker>(
self,
event_handler: impl EventHandlerValue<MouseData, __Marker>,
) -> <Self as AttributeBuilderTarget>::Output
fn onmouseenter<__Marker>( self, event_handler: impl EventHandlerValue<MouseData, __Marker>, ) -> <Self as AttributeBuilderTarget>::Output
onmouseenter
General Event Handler Information
§Event Handlers
Event Handlers let you react to user input in your application. In Dioxus, event handlers accept a closure that is called when the event occurs:
use dioxus::prelude::*;
fn App() -> Element {
rsx! {
button {
// The `onclick` event accepts a closure with the signature `fn(Event)`
onclick: |event_data| println!("clicked! I got the event data: {event_data:?}"),
"Click me"
}
}
}§Event Lifetimes
Events take a closure with the 'static lifetime. This means that the closure can only access data that either exists for the entire lifetime of the application, or data that you move into the closure.
State in dioxus is copy which makes it very easy to move into 'static closures like event handlers:
let mut count = use_signal(|| 0);
rsx! {
button {
// Since we added the `move` keyword, the closure will move the `count` signal into the closure
onclick: move |_| {
// This will panic because the `count` signal is not in scope
count.set(count() + 1);
},
"Click me"
}
};If you need to access data that is not Copy, you may need to clone the data before you move it into the closure:
// String is not `Copy`
let string = "hello world".to_string();
rsx! {
button {
// The string only has one owner. We could move it into this closure, but since we want to use the string in other closures later, we will clone it instead
onclick: {
// Clone the string in a new block
let string = string.clone();
// Then move the cloned string into the closure
move |_| println!("{}", string)
},
"Print hello world"
}
button {
// We don't use the string after this closure, so we can just move it into the closure directly
onclick: move |_| println!("{}", string),
"Print hello world again"
}
};§Async Event Handlers
In addition to closures that return nothing, you can also use async closures to handle events. If you return an async block from an event handler, dioxus will automatically spawn it:
use dioxus::prelude::*;
fn App() -> Element {
rsx! {
button {
// The `onclick` event can also accept a closure that returns an async block
onclick: move |_| async move {
tokio::time::sleep(std::time::Duration::from_secs(1)).await;
println!("You clicked the button one second ago!");
},
"Click me"
}
}
}§Compiler errors you may run into while using event handlers
function requires argument type to outlive `'static`
Event handler in Dioxus need only access data that can last for the entire lifetime of the application. That generally means data that is moved into the closure. If you get this error, you may have forgotten to add move to your closure.
Broken component:
// We return an Element which can last as long as the component is on the screen
fn App() -> Element {
// Signals are `Copy` which makes them very easy to move into `'static` closures like event handlers
let state = use_signal(|| "hello world".to_string());
rsx! {
button {
// ❌ Without `move`, rust will try to borrow the `state` signal which fails because the state signal is dropped at the end of the function
onclick: |_| {
println!("You clicked the button! The state is: {state}");
},
"Click me"
}
}
// The state signal is dropped here, but the event handler still needs to access it
}Fixed component:
fn App() -> Element {
let state = use_signal(|| "hello world".to_string());
rsx! {
button {
// ✅ The `move` keyword tells rust it can move the `state` signal into the closure. Since the closure owns the signal state, it can read it even after the function returns
onclick: move |_| {
println!("You clicked the button! The state is: {state}");
},
"Click me"
}
}
}use of moved value: `your_value` value used here after move
Data in rust has a single owner. If you run into this error, you have likely tried to move data that isn’t Copy into two different closures. You can fix this issue by making your data Copy or calling clone on it before you move it into the closure.
Broken component:
// `MyComponent` accepts a string which cannot be copied implicitly
#[component]
fn MyComponent(string: String) -> Element {
rsx! {
button {
// ❌ We are moving the string into the onclick handler which means we can't access it elsewhere
onclick: move |_| {
println!("{string}");
},
"Print hello world"
}
button {
// ❌ Since we already moved the string, we can't move it into the onclick handler again. This will cause a compiler error
onclick: move |_| {
println!("{string}");
},
"Print hello world again"
}
}
}You can fix this issue by either:
- Making your data
CopywithReadSignal:
// `MyComponent` accepts `ReadSignal<String>` which implements `Copy`
#[component]
fn MyComponent(string: ReadSignal<String>) -> Element {
rsx! {
button {
// ✅ Because the `string` signal is `Copy`, we can copy it into the closure while still having access to it elsewhere
onclick: move |_| println!("{}", string),
"Print hello world"
}
button {
// ✅ Since `string` is `Copy`, we can move it into the onclick handler again
onclick: move |_| println!("{}", string),
"Print hello world again"
}
}
}- Calling
cloneon your data before you move it into the closure:
// `MyComponent` accepts a string which doesn't implement `Copy`
#[component]
fn MyComponent(string: String) -> Element {
rsx! {
button {
// ✅ The string only has one owner. We could move it into this closure, but since we want to use the string in other closures later, we will clone it instead
onclick: {
// Clone the string in a new block
let string = string.clone();
// Then move the cloned string into the closure
move |_| println!("{}", string)
},
"Print hello world"
}
button {
// ✅ We don't use the string after this closure, so we can just move it into the closure directly
onclick: move |_| println!("{}", string),
"Print hello world again"
}
}
}Sourcefn onmouseleave<__Marker>(
self,
event_handler: impl EventHandlerValue<MouseData, __Marker>,
) -> <Self as AttributeBuilderTarget>::Output
fn onmouseleave<__Marker>( self, event_handler: impl EventHandlerValue<MouseData, __Marker>, ) -> <Self as AttributeBuilderTarget>::Output
onmouseleave
General Event Handler Information
§Event Handlers
Event Handlers let you react to user input in your application. In Dioxus, event handlers accept a closure that is called when the event occurs:
use dioxus::prelude::*;
fn App() -> Element {
rsx! {
button {
// The `onclick` event accepts a closure with the signature `fn(Event)`
onclick: |event_data| println!("clicked! I got the event data: {event_data:?}"),
"Click me"
}
}
}§Event Lifetimes
Events take a closure with the 'static lifetime. This means that the closure can only access data that either exists for the entire lifetime of the application, or data that you move into the closure.
State in dioxus is copy which makes it very easy to move into 'static closures like event handlers:
let mut count = use_signal(|| 0);
rsx! {
button {
// Since we added the `move` keyword, the closure will move the `count` signal into the closure
onclick: move |_| {
// This will panic because the `count` signal is not in scope
count.set(count() + 1);
},
"Click me"
}
};If you need to access data that is not Copy, you may need to clone the data before you move it into the closure:
// String is not `Copy`
let string = "hello world".to_string();
rsx! {
button {
// The string only has one owner. We could move it into this closure, but since we want to use the string in other closures later, we will clone it instead
onclick: {
// Clone the string in a new block
let string = string.clone();
// Then move the cloned string into the closure
move |_| println!("{}", string)
},
"Print hello world"
}
button {
// We don't use the string after this closure, so we can just move it into the closure directly
onclick: move |_| println!("{}", string),
"Print hello world again"
}
};§Async Event Handlers
In addition to closures that return nothing, you can also use async closures to handle events. If you return an async block from an event handler, dioxus will automatically spawn it:
use dioxus::prelude::*;
fn App() -> Element {
rsx! {
button {
// The `onclick` event can also accept a closure that returns an async block
onclick: move |_| async move {
tokio::time::sleep(std::time::Duration::from_secs(1)).await;
println!("You clicked the button one second ago!");
},
"Click me"
}
}
}§Compiler errors you may run into while using event handlers
function requires argument type to outlive `'static`
Event handler in Dioxus need only access data that can last for the entire lifetime of the application. That generally means data that is moved into the closure. If you get this error, you may have forgotten to add move to your closure.
Broken component:
// We return an Element which can last as long as the component is on the screen
fn App() -> Element {
// Signals are `Copy` which makes them very easy to move into `'static` closures like event handlers
let state = use_signal(|| "hello world".to_string());
rsx! {
button {
// ❌ Without `move`, rust will try to borrow the `state` signal which fails because the state signal is dropped at the end of the function
onclick: |_| {
println!("You clicked the button! The state is: {state}");
},
"Click me"
}
}
// The state signal is dropped here, but the event handler still needs to access it
}Fixed component:
fn App() -> Element {
let state = use_signal(|| "hello world".to_string());
rsx! {
button {
// ✅ The `move` keyword tells rust it can move the `state` signal into the closure. Since the closure owns the signal state, it can read it even after the function returns
onclick: move |_| {
println!("You clicked the button! The state is: {state}");
},
"Click me"
}
}
}use of moved value: `your_value` value used here after move
Data in rust has a single owner. If you run into this error, you have likely tried to move data that isn’t Copy into two different closures. You can fix this issue by making your data Copy or calling clone on it before you move it into the closure.
Broken component:
// `MyComponent` accepts a string which cannot be copied implicitly
#[component]
fn MyComponent(string: String) -> Element {
rsx! {
button {
// ❌ We are moving the string into the onclick handler which means we can't access it elsewhere
onclick: move |_| {
println!("{string}");
},
"Print hello world"
}
button {
// ❌ Since we already moved the string, we can't move it into the onclick handler again. This will cause a compiler error
onclick: move |_| {
println!("{string}");
},
"Print hello world again"
}
}
}You can fix this issue by either:
- Making your data
CopywithReadSignal:
// `MyComponent` accepts `ReadSignal<String>` which implements `Copy`
#[component]
fn MyComponent(string: ReadSignal<String>) -> Element {
rsx! {
button {
// ✅ Because the `string` signal is `Copy`, we can copy it into the closure while still having access to it elsewhere
onclick: move |_| println!("{}", string),
"Print hello world"
}
button {
// ✅ Since `string` is `Copy`, we can move it into the onclick handler again
onclick: move |_| println!("{}", string),
"Print hello world again"
}
}
}- Calling
cloneon your data before you move it into the closure:
// `MyComponent` accepts a string which doesn't implement `Copy`
#[component]
fn MyComponent(string: String) -> Element {
rsx! {
button {
// ✅ The string only has one owner. We could move it into this closure, but since we want to use the string in other closures later, we will clone it instead
onclick: {
// Clone the string in a new block
let string = string.clone();
// Then move the cloned string into the closure
move |_| println!("{}", string)
},
"Print hello world"
}
button {
// ✅ We don't use the string after this closure, so we can just move it into the closure directly
onclick: move |_| println!("{}", string),
"Print hello world again"
}
}
}Sourcefn onmousemove<__Marker>(
self,
event_handler: impl EventHandlerValue<MouseData, __Marker>,
) -> <Self as AttributeBuilderTarget>::Output
fn onmousemove<__Marker>( self, event_handler: impl EventHandlerValue<MouseData, __Marker>, ) -> <Self as AttributeBuilderTarget>::Output
onmousemove
General Event Handler Information
§Event Handlers
Event Handlers let you react to user input in your application. In Dioxus, event handlers accept a closure that is called when the event occurs:
use dioxus::prelude::*;
fn App() -> Element {
rsx! {
button {
// The `onclick` event accepts a closure with the signature `fn(Event)`
onclick: |event_data| println!("clicked! I got the event data: {event_data:?}"),
"Click me"
}
}
}§Event Lifetimes
Events take a closure with the 'static lifetime. This means that the closure can only access data that either exists for the entire lifetime of the application, or data that you move into the closure.
State in dioxus is copy which makes it very easy to move into 'static closures like event handlers:
let mut count = use_signal(|| 0);
rsx! {
button {
// Since we added the `move` keyword, the closure will move the `count` signal into the closure
onclick: move |_| {
// This will panic because the `count` signal is not in scope
count.set(count() + 1);
},
"Click me"
}
};If you need to access data that is not Copy, you may need to clone the data before you move it into the closure:
// String is not `Copy`
let string = "hello world".to_string();
rsx! {
button {
// The string only has one owner. We could move it into this closure, but since we want to use the string in other closures later, we will clone it instead
onclick: {
// Clone the string in a new block
let string = string.clone();
// Then move the cloned string into the closure
move |_| println!("{}", string)
},
"Print hello world"
}
button {
// We don't use the string after this closure, so we can just move it into the closure directly
onclick: move |_| println!("{}", string),
"Print hello world again"
}
};§Async Event Handlers
In addition to closures that return nothing, you can also use async closures to handle events. If you return an async block from an event handler, dioxus will automatically spawn it:
use dioxus::prelude::*;
fn App() -> Element {
rsx! {
button {
// The `onclick` event can also accept a closure that returns an async block
onclick: move |_| async move {
tokio::time::sleep(std::time::Duration::from_secs(1)).await;
println!("You clicked the button one second ago!");
},
"Click me"
}
}
}§Compiler errors you may run into while using event handlers
function requires argument type to outlive `'static`
Event handler in Dioxus need only access data that can last for the entire lifetime of the application. That generally means data that is moved into the closure. If you get this error, you may have forgotten to add move to your closure.
Broken component:
// We return an Element which can last as long as the component is on the screen
fn App() -> Element {
// Signals are `Copy` which makes them very easy to move into `'static` closures like event handlers
let state = use_signal(|| "hello world".to_string());
rsx! {
button {
// ❌ Without `move`, rust will try to borrow the `state` signal which fails because the state signal is dropped at the end of the function
onclick: |_| {
println!("You clicked the button! The state is: {state}");
},
"Click me"
}
}
// The state signal is dropped here, but the event handler still needs to access it
}Fixed component:
fn App() -> Element {
let state = use_signal(|| "hello world".to_string());
rsx! {
button {
// ✅ The `move` keyword tells rust it can move the `state` signal into the closure. Since the closure owns the signal state, it can read it even after the function returns
onclick: move |_| {
println!("You clicked the button! The state is: {state}");
},
"Click me"
}
}
}use of moved value: `your_value` value used here after move
Data in rust has a single owner. If you run into this error, you have likely tried to move data that isn’t Copy into two different closures. You can fix this issue by making your data Copy or calling clone on it before you move it into the closure.
Broken component:
// `MyComponent` accepts a string which cannot be copied implicitly
#[component]
fn MyComponent(string: String) -> Element {
rsx! {
button {
// ❌ We are moving the string into the onclick handler which means we can't access it elsewhere
onclick: move |_| {
println!("{string}");
},
"Print hello world"
}
button {
// ❌ Since we already moved the string, we can't move it into the onclick handler again. This will cause a compiler error
onclick: move |_| {
println!("{string}");
},
"Print hello world again"
}
}
}You can fix this issue by either:
- Making your data
CopywithReadSignal:
// `MyComponent` accepts `ReadSignal<String>` which implements `Copy`
#[component]
fn MyComponent(string: ReadSignal<String>) -> Element {
rsx! {
button {
// ✅ Because the `string` signal is `Copy`, we can copy it into the closure while still having access to it elsewhere
onclick: move |_| println!("{}", string),
"Print hello world"
}
button {
// ✅ Since `string` is `Copy`, we can move it into the onclick handler again
onclick: move |_| println!("{}", string),
"Print hello world again"
}
}
}- Calling
cloneon your data before you move it into the closure:
// `MyComponent` accepts a string which doesn't implement `Copy`
#[component]
fn MyComponent(string: String) -> Element {
rsx! {
button {
// ✅ The string only has one owner. We could move it into this closure, but since we want to use the string in other closures later, we will clone it instead
onclick: {
// Clone the string in a new block
let string = string.clone();
// Then move the cloned string into the closure
move |_| println!("{}", string)
},
"Print hello world"
}
button {
// ✅ We don't use the string after this closure, so we can just move it into the closure directly
onclick: move |_| println!("{}", string),
"Print hello world again"
}
}
}Sourcefn onmouseout<__Marker>(
self,
event_handler: impl EventHandlerValue<MouseData, __Marker>,
) -> <Self as AttributeBuilderTarget>::Output
fn onmouseout<__Marker>( self, event_handler: impl EventHandlerValue<MouseData, __Marker>, ) -> <Self as AttributeBuilderTarget>::Output
onmouseout
General Event Handler Information
§Event Handlers
Event Handlers let you react to user input in your application. In Dioxus, event handlers accept a closure that is called when the event occurs:
use dioxus::prelude::*;
fn App() -> Element {
rsx! {
button {
// The `onclick` event accepts a closure with the signature `fn(Event)`
onclick: |event_data| println!("clicked! I got the event data: {event_data:?}"),
"Click me"
}
}
}§Event Lifetimes
Events take a closure with the 'static lifetime. This means that the closure can only access data that either exists for the entire lifetime of the application, or data that you move into the closure.
State in dioxus is copy which makes it very easy to move into 'static closures like event handlers:
let mut count = use_signal(|| 0);
rsx! {
button {
// Since we added the `move` keyword, the closure will move the `count` signal into the closure
onclick: move |_| {
// This will panic because the `count` signal is not in scope
count.set(count() + 1);
},
"Click me"
}
};If you need to access data that is not Copy, you may need to clone the data before you move it into the closure:
// String is not `Copy`
let string = "hello world".to_string();
rsx! {
button {
// The string only has one owner. We could move it into this closure, but since we want to use the string in other closures later, we will clone it instead
onclick: {
// Clone the string in a new block
let string = string.clone();
// Then move the cloned string into the closure
move |_| println!("{}", string)
},
"Print hello world"
}
button {
// We don't use the string after this closure, so we can just move it into the closure directly
onclick: move |_| println!("{}", string),
"Print hello world again"
}
};§Async Event Handlers
In addition to closures that return nothing, you can also use async closures to handle events. If you return an async block from an event handler, dioxus will automatically spawn it:
use dioxus::prelude::*;
fn App() -> Element {
rsx! {
button {
// The `onclick` event can also accept a closure that returns an async block
onclick: move |_| async move {
tokio::time::sleep(std::time::Duration::from_secs(1)).await;
println!("You clicked the button one second ago!");
},
"Click me"
}
}
}§Compiler errors you may run into while using event handlers
function requires argument type to outlive `'static`
Event handler in Dioxus need only access data that can last for the entire lifetime of the application. That generally means data that is moved into the closure. If you get this error, you may have forgotten to add move to your closure.
Broken component:
// We return an Element which can last as long as the component is on the screen
fn App() -> Element {
// Signals are `Copy` which makes them very easy to move into `'static` closures like event handlers
let state = use_signal(|| "hello world".to_string());
rsx! {
button {
// ❌ Without `move`, rust will try to borrow the `state` signal which fails because the state signal is dropped at the end of the function
onclick: |_| {
println!("You clicked the button! The state is: {state}");
},
"Click me"
}
}
// The state signal is dropped here, but the event handler still needs to access it
}Fixed component:
fn App() -> Element {
let state = use_signal(|| "hello world".to_string());
rsx! {
button {
// ✅ The `move` keyword tells rust it can move the `state` signal into the closure. Since the closure owns the signal state, it can read it even after the function returns
onclick: move |_| {
println!("You clicked the button! The state is: {state}");
},
"Click me"
}
}
}use of moved value: `your_value` value used here after move
Data in rust has a single owner. If you run into this error, you have likely tried to move data that isn’t Copy into two different closures. You can fix this issue by making your data Copy or calling clone on it before you move it into the closure.
Broken component:
// `MyComponent` accepts a string which cannot be copied implicitly
#[component]
fn MyComponent(string: String) -> Element {
rsx! {
button {
// ❌ We are moving the string into the onclick handler which means we can't access it elsewhere
onclick: move |_| {
println!("{string}");
},
"Print hello world"
}
button {
// ❌ Since we already moved the string, we can't move it into the onclick handler again. This will cause a compiler error
onclick: move |_| {
println!("{string}");
},
"Print hello world again"
}
}
}You can fix this issue by either:
- Making your data
CopywithReadSignal:
// `MyComponent` accepts `ReadSignal<String>` which implements `Copy`
#[component]
fn MyComponent(string: ReadSignal<String>) -> Element {
rsx! {
button {
// ✅ Because the `string` signal is `Copy`, we can copy it into the closure while still having access to it elsewhere
onclick: move |_| println!("{}", string),
"Print hello world"
}
button {
// ✅ Since `string` is `Copy`, we can move it into the onclick handler again
onclick: move |_| println!("{}", string),
"Print hello world again"
}
}
}- Calling
cloneon your data before you move it into the closure:
// `MyComponent` accepts a string which doesn't implement `Copy`
#[component]
fn MyComponent(string: String) -> Element {
rsx! {
button {
// ✅ The string only has one owner. We could move it into this closure, but since we want to use the string in other closures later, we will clone it instead
onclick: {
// Clone the string in a new block
let string = string.clone();
// Then move the cloned string into the closure
move |_| println!("{}", string)
},
"Print hello world"
}
button {
// ✅ We don't use the string after this closure, so we can just move it into the closure directly
onclick: move |_| println!("{}", string),
"Print hello world again"
}
}
}Sourcefn onmouseover<__Marker>(
self,
event_handler: impl EventHandlerValue<MouseData, __Marker>,
) -> <Self as AttributeBuilderTarget>::Output
fn onmouseover<__Marker>( self, event_handler: impl EventHandlerValue<MouseData, __Marker>, ) -> <Self as AttributeBuilderTarget>::Output
onmouseover Triggered when the users’s mouse hovers over an element.
General Event Handler Information
§Event Handlers
Event Handlers let you react to user input in your application. In Dioxus, event handlers accept a closure that is called when the event occurs:
use dioxus::prelude::*;
fn App() -> Element {
rsx! {
button {
// The `onclick` event accepts a closure with the signature `fn(Event)`
onclick: |event_data| println!("clicked! I got the event data: {event_data:?}"),
"Click me"
}
}
}§Event Lifetimes
Events take a closure with the 'static lifetime. This means that the closure can only access data that either exists for the entire lifetime of the application, or data that you move into the closure.
State in dioxus is copy which makes it very easy to move into 'static closures like event handlers:
let mut count = use_signal(|| 0);
rsx! {
button {
// Since we added the `move` keyword, the closure will move the `count` signal into the closure
onclick: move |_| {
// This will panic because the `count` signal is not in scope
count.set(count() + 1);
},
"Click me"
}
};If you need to access data that is not Copy, you may need to clone the data before you move it into the closure:
// String is not `Copy`
let string = "hello world".to_string();
rsx! {
button {
// The string only has one owner. We could move it into this closure, but since we want to use the string in other closures later, we will clone it instead
onclick: {
// Clone the string in a new block
let string = string.clone();
// Then move the cloned string into the closure
move |_| println!("{}", string)
},
"Print hello world"
}
button {
// We don't use the string after this closure, so we can just move it into the closure directly
onclick: move |_| println!("{}", string),
"Print hello world again"
}
};§Async Event Handlers
In addition to closures that return nothing, you can also use async closures to handle events. If you return an async block from an event handler, dioxus will automatically spawn it:
use dioxus::prelude::*;
fn App() -> Element {
rsx! {
button {
// The `onclick` event can also accept a closure that returns an async block
onclick: move |_| async move {
tokio::time::sleep(std::time::Duration::from_secs(1)).await;
println!("You clicked the button one second ago!");
},
"Click me"
}
}
}§Compiler errors you may run into while using event handlers
function requires argument type to outlive `'static`
Event handler in Dioxus need only access data that can last for the entire lifetime of the application. That generally means data that is moved into the closure. If you get this error, you may have forgotten to add move to your closure.
Broken component:
// We return an Element which can last as long as the component is on the screen
fn App() -> Element {
// Signals are `Copy` which makes them very easy to move into `'static` closures like event handlers
let state = use_signal(|| "hello world".to_string());
rsx! {
button {
// ❌ Without `move`, rust will try to borrow the `state` signal which fails because the state signal is dropped at the end of the function
onclick: |_| {
println!("You clicked the button! The state is: {state}");
},
"Click me"
}
}
// The state signal is dropped here, but the event handler still needs to access it
}Fixed component:
fn App() -> Element {
let state = use_signal(|| "hello world".to_string());
rsx! {
button {
// ✅ The `move` keyword tells rust it can move the `state` signal into the closure. Since the closure owns the signal state, it can read it even after the function returns
onclick: move |_| {
println!("You clicked the button! The state is: {state}");
},
"Click me"
}
}
}use of moved value: `your_value` value used here after move
Data in rust has a single owner. If you run into this error, you have likely tried to move data that isn’t Copy into two different closures. You can fix this issue by making your data Copy or calling clone on it before you move it into the closure.
Broken component:
// `MyComponent` accepts a string which cannot be copied implicitly
#[component]
fn MyComponent(string: String) -> Element {
rsx! {
button {
// ❌ We are moving the string into the onclick handler which means we can't access it elsewhere
onclick: move |_| {
println!("{string}");
},
"Print hello world"
}
button {
// ❌ Since we already moved the string, we can't move it into the onclick handler again. This will cause a compiler error
onclick: move |_| {
println!("{string}");
},
"Print hello world again"
}
}
}You can fix this issue by either:
- Making your data
CopywithReadSignal:
// `MyComponent` accepts `ReadSignal<String>` which implements `Copy`
#[component]
fn MyComponent(string: ReadSignal<String>) -> Element {
rsx! {
button {
// ✅ Because the `string` signal is `Copy`, we can copy it into the closure while still having access to it elsewhere
onclick: move |_| println!("{}", string),
"Print hello world"
}
button {
// ✅ Since `string` is `Copy`, we can move it into the onclick handler again
onclick: move |_| println!("{}", string),
"Print hello world again"
}
}
}- Calling
cloneon your data before you move it into the closure:
// `MyComponent` accepts a string which doesn't implement `Copy`
#[component]
fn MyComponent(string: String) -> Element {
rsx! {
button {
// ✅ The string only has one owner. We could move it into this closure, but since we want to use the string in other closures later, we will clone it instead
onclick: {
// Clone the string in a new block
let string = string.clone();
// Then move the cloned string into the closure
move |_| println!("{}", string)
},
"Print hello world"
}
button {
// ✅ We don't use the string after this closure, so we can just move it into the closure directly
onclick: move |_| println!("{}", string),
"Print hello world again"
}
}
}Sourcefn onmouseup<__Marker>(
self,
event_handler: impl EventHandlerValue<MouseData, __Marker>,
) -> <Self as AttributeBuilderTarget>::Output
fn onmouseup<__Marker>( self, event_handler: impl EventHandlerValue<MouseData, __Marker>, ) -> <Self as AttributeBuilderTarget>::Output
onmouseup
General Event Handler Information
§Event Handlers
Event Handlers let you react to user input in your application. In Dioxus, event handlers accept a closure that is called when the event occurs:
use dioxus::prelude::*;
fn App() -> Element {
rsx! {
button {
// The `onclick` event accepts a closure with the signature `fn(Event)`
onclick: |event_data| println!("clicked! I got the event data: {event_data:?}"),
"Click me"
}
}
}§Event Lifetimes
Events take a closure with the 'static lifetime. This means that the closure can only access data that either exists for the entire lifetime of the application, or data that you move into the closure.
State in dioxus is copy which makes it very easy to move into 'static closures like event handlers:
let mut count = use_signal(|| 0);
rsx! {
button {
// Since we added the `move` keyword, the closure will move the `count` signal into the closure
onclick: move |_| {
// This will panic because the `count` signal is not in scope
count.set(count() + 1);
},
"Click me"
}
};If you need to access data that is not Copy, you may need to clone the data before you move it into the closure:
// String is not `Copy`
let string = "hello world".to_string();
rsx! {
button {
// The string only has one owner. We could move it into this closure, but since we want to use the string in other closures later, we will clone it instead
onclick: {
// Clone the string in a new block
let string = string.clone();
// Then move the cloned string into the closure
move |_| println!("{}", string)
},
"Print hello world"
}
button {
// We don't use the string after this closure, so we can just move it into the closure directly
onclick: move |_| println!("{}", string),
"Print hello world again"
}
};§Async Event Handlers
In addition to closures that return nothing, you can also use async closures to handle events. If you return an async block from an event handler, dioxus will automatically spawn it:
use dioxus::prelude::*;
fn App() -> Element {
rsx! {
button {
// The `onclick` event can also accept a closure that returns an async block
onclick: move |_| async move {
tokio::time::sleep(std::time::Duration::from_secs(1)).await;
println!("You clicked the button one second ago!");
},
"Click me"
}
}
}§Compiler errors you may run into while using event handlers
function requires argument type to outlive `'static`
Event handler in Dioxus need only access data that can last for the entire lifetime of the application. That generally means data that is moved into the closure. If you get this error, you may have forgotten to add move to your closure.
Broken component:
// We return an Element which can last as long as the component is on the screen
fn App() -> Element {
// Signals are `Copy` which makes them very easy to move into `'static` closures like event handlers
let state = use_signal(|| "hello world".to_string());
rsx! {
button {
// ❌ Without `move`, rust will try to borrow the `state` signal which fails because the state signal is dropped at the end of the function
onclick: |_| {
println!("You clicked the button! The state is: {state}");
},
"Click me"
}
}
// The state signal is dropped here, but the event handler still needs to access it
}Fixed component:
fn App() -> Element {
let state = use_signal(|| "hello world".to_string());
rsx! {
button {
// ✅ The `move` keyword tells rust it can move the `state` signal into the closure. Since the closure owns the signal state, it can read it even after the function returns
onclick: move |_| {
println!("You clicked the button! The state is: {state}");
},
"Click me"
}
}
}use of moved value: `your_value` value used here after move
Data in rust has a single owner. If you run into this error, you have likely tried to move data that isn’t Copy into two different closures. You can fix this issue by making your data Copy or calling clone on it before you move it into the closure.
Broken component:
// `MyComponent` accepts a string which cannot be copied implicitly
#[component]
fn MyComponent(string: String) -> Element {
rsx! {
button {
// ❌ We are moving the string into the onclick handler which means we can't access it elsewhere
onclick: move |_| {
println!("{string}");
},
"Print hello world"
}
button {
// ❌ Since we already moved the string, we can't move it into the onclick handler again. This will cause a compiler error
onclick: move |_| {
println!("{string}");
},
"Print hello world again"
}
}
}You can fix this issue by either:
- Making your data
CopywithReadSignal:
// `MyComponent` accepts `ReadSignal<String>` which implements `Copy`
#[component]
fn MyComponent(string: ReadSignal<String>) -> Element {
rsx! {
button {
// ✅ Because the `string` signal is `Copy`, we can copy it into the closure while still having access to it elsewhere
onclick: move |_| println!("{}", string),
"Print hello world"
}
button {
// ✅ Since `string` is `Copy`, we can move it into the onclick handler again
onclick: move |_| println!("{}", string),
"Print hello world again"
}
}
}- Calling
cloneon your data before you move it into the closure:
// `MyComponent` accepts a string which doesn't implement `Copy`
#[component]
fn MyComponent(string: String) -> Element {
rsx! {
button {
// ✅ The string only has one owner. We could move it into this closure, but since we want to use the string in other closures later, we will clone it instead
onclick: {
// Clone the string in a new block
let string = string.clone();
// Then move the cloned string into the closure
move |_| println!("{}", string)
},
"Print hello world"
}
button {
// ✅ We don't use the string after this closure, so we can just move it into the closure directly
onclick: move |_| println!("{}", string),
"Print hello world again"
}
}
}Sourcefn onpointerdown<__Marker>(
self,
event_handler: impl EventHandlerValue<PointerData, __Marker>,
) -> <Self as AttributeBuilderTarget>::Output
fn onpointerdown<__Marker>( self, event_handler: impl EventHandlerValue<PointerData, __Marker>, ) -> <Self as AttributeBuilderTarget>::Output
onpointerdown
General Event Handler Information
§Event Handlers
Event Handlers let you react to user input in your application. In Dioxus, event handlers accept a closure that is called when the event occurs:
use dioxus::prelude::*;
fn App() -> Element {
rsx! {
button {
// The `onclick` event accepts a closure with the signature `fn(Event)`
onclick: |event_data| println!("clicked! I got the event data: {event_data:?}"),
"Click me"
}
}
}§Event Lifetimes
Events take a closure with the 'static lifetime. This means that the closure can only access data that either exists for the entire lifetime of the application, or data that you move into the closure.
State in dioxus is copy which makes it very easy to move into 'static closures like event handlers:
let mut count = use_signal(|| 0);
rsx! {
button {
// Since we added the `move` keyword, the closure will move the `count` signal into the closure
onclick: move |_| {
// This will panic because the `count` signal is not in scope
count.set(count() + 1);
},
"Click me"
}
};If you need to access data that is not Copy, you may need to clone the data before you move it into the closure:
// String is not `Copy`
let string = "hello world".to_string();
rsx! {
button {
// The string only has one owner. We could move it into this closure, but since we want to use the string in other closures later, we will clone it instead
onclick: {
// Clone the string in a new block
let string = string.clone();
// Then move the cloned string into the closure
move |_| println!("{}", string)
},
"Print hello world"
}
button {
// We don't use the string after this closure, so we can just move it into the closure directly
onclick: move |_| println!("{}", string),
"Print hello world again"
}
};§Async Event Handlers
In addition to closures that return nothing, you can also use async closures to handle events. If you return an async block from an event handler, dioxus will automatically spawn it:
use dioxus::prelude::*;
fn App() -> Element {
rsx! {
button {
// The `onclick` event can also accept a closure that returns an async block
onclick: move |_| async move {
tokio::time::sleep(std::time::Duration::from_secs(1)).await;
println!("You clicked the button one second ago!");
},
"Click me"
}
}
}§Compiler errors you may run into while using event handlers
function requires argument type to outlive `'static`
Event handler in Dioxus need only access data that can last for the entire lifetime of the application. That generally means data that is moved into the closure. If you get this error, you may have forgotten to add move to your closure.
Broken component:
// We return an Element which can last as long as the component is on the screen
fn App() -> Element {
// Signals are `Copy` which makes them very easy to move into `'static` closures like event handlers
let state = use_signal(|| "hello world".to_string());
rsx! {
button {
// ❌ Without `move`, rust will try to borrow the `state` signal which fails because the state signal is dropped at the end of the function
onclick: |_| {
println!("You clicked the button! The state is: {state}");
},
"Click me"
}
}
// The state signal is dropped here, but the event handler still needs to access it
}Fixed component:
fn App() -> Element {
let state = use_signal(|| "hello world".to_string());
rsx! {
button {
// ✅ The `move` keyword tells rust it can move the `state` signal into the closure. Since the closure owns the signal state, it can read it even after the function returns
onclick: move |_| {
println!("You clicked the button! The state is: {state}");
},
"Click me"
}
}
}use of moved value: `your_value` value used here after move
Data in rust has a single owner. If you run into this error, you have likely tried to move data that isn’t Copy into two different closures. You can fix this issue by making your data Copy or calling clone on it before you move it into the closure.
Broken component:
// `MyComponent` accepts a string which cannot be copied implicitly
#[component]
fn MyComponent(string: String) -> Element {
rsx! {
button {
// ❌ We are moving the string into the onclick handler which means we can't access it elsewhere
onclick: move |_| {
println!("{string}");
},
"Print hello world"
}
button {
// ❌ Since we already moved the string, we can't move it into the onclick handler again. This will cause a compiler error
onclick: move |_| {
println!("{string}");
},
"Print hello world again"
}
}
}You can fix this issue by either:
- Making your data
CopywithReadSignal:
// `MyComponent` accepts `ReadSignal<String>` which implements `Copy`
#[component]
fn MyComponent(string: ReadSignal<String>) -> Element {
rsx! {
button {
// ✅ Because the `string` signal is `Copy`, we can copy it into the closure while still having access to it elsewhere
onclick: move |_| println!("{}", string),
"Print hello world"
}
button {
// ✅ Since `string` is `Copy`, we can move it into the onclick handler again
onclick: move |_| println!("{}", string),
"Print hello world again"
}
}
}- Calling
cloneon your data before you move it into the closure:
// `MyComponent` accepts a string which doesn't implement `Copy`
#[component]
fn MyComponent(string: String) -> Element {
rsx! {
button {
// ✅ The string only has one owner. We could move it into this closure, but since we want to use the string in other closures later, we will clone it instead
onclick: {
// Clone the string in a new block
let string = string.clone();
// Then move the cloned string into the closure
move |_| println!("{}", string)
},
"Print hello world"
}
button {
// ✅ We don't use the string after this closure, so we can just move it into the closure directly
onclick: move |_| println!("{}", string),
"Print hello world again"
}
}
}Sourcefn onpointermove<__Marker>(
self,
event_handler: impl EventHandlerValue<PointerData, __Marker>,
) -> <Self as AttributeBuilderTarget>::Output
fn onpointermove<__Marker>( self, event_handler: impl EventHandlerValue<PointerData, __Marker>, ) -> <Self as AttributeBuilderTarget>::Output
onpointermove
General Event Handler Information
§Event Handlers
Event Handlers let you react to user input in your application. In Dioxus, event handlers accept a closure that is called when the event occurs:
use dioxus::prelude::*;
fn App() -> Element {
rsx! {
button {
// The `onclick` event accepts a closure with the signature `fn(Event)`
onclick: |event_data| println!("clicked! I got the event data: {event_data:?}"),
"Click me"
}
}
}§Event Lifetimes
Events take a closure with the 'static lifetime. This means that the closure can only access data that either exists for the entire lifetime of the application, or data that you move into the closure.
State in dioxus is copy which makes it very easy to move into 'static closures like event handlers:
let mut count = use_signal(|| 0);
rsx! {
button {
// Since we added the `move` keyword, the closure will move the `count` signal into the closure
onclick: move |_| {
// This will panic because the `count` signal is not in scope
count.set(count() + 1);
},
"Click me"
}
};If you need to access data that is not Copy, you may need to clone the data before you move it into the closure:
// String is not `Copy`
let string = "hello world".to_string();
rsx! {
button {
// The string only has one owner. We could move it into this closure, but since we want to use the string in other closures later, we will clone it instead
onclick: {
// Clone the string in a new block
let string = string.clone();
// Then move the cloned string into the closure
move |_| println!("{}", string)
},
"Print hello world"
}
button {
// We don't use the string after this closure, so we can just move it into the closure directly
onclick: move |_| println!("{}", string),
"Print hello world again"
}
};§Async Event Handlers
In addition to closures that return nothing, you can also use async closures to handle events. If you return an async block from an event handler, dioxus will automatically spawn it:
use dioxus::prelude::*;
fn App() -> Element {
rsx! {
button {
// The `onclick` event can also accept a closure that returns an async block
onclick: move |_| async move {
tokio::time::sleep(std::time::Duration::from_secs(1)).await;
println!("You clicked the button one second ago!");
},
"Click me"
}
}
}§Compiler errors you may run into while using event handlers
function requires argument type to outlive `'static`
Event handler in Dioxus need only access data that can last for the entire lifetime of the application. That generally means data that is moved into the closure. If you get this error, you may have forgotten to add move to your closure.
Broken component:
// We return an Element which can last as long as the component is on the screen
fn App() -> Element {
// Signals are `Copy` which makes them very easy to move into `'static` closures like event handlers
let state = use_signal(|| "hello world".to_string());
rsx! {
button {
// ❌ Without `move`, rust will try to borrow the `state` signal which fails because the state signal is dropped at the end of the function
onclick: |_| {
println!("You clicked the button! The state is: {state}");
},
"Click me"
}
}
// The state signal is dropped here, but the event handler still needs to access it
}Fixed component:
fn App() -> Element {
let state = use_signal(|| "hello world".to_string());
rsx! {
button {
// ✅ The `move` keyword tells rust it can move the `state` signal into the closure. Since the closure owns the signal state, it can read it even after the function returns
onclick: move |_| {
println!("You clicked the button! The state is: {state}");
},
"Click me"
}
}
}use of moved value: `your_value` value used here after move
Data in rust has a single owner. If you run into this error, you have likely tried to move data that isn’t Copy into two different closures. You can fix this issue by making your data Copy or calling clone on it before you move it into the closure.
Broken component:
// `MyComponent` accepts a string which cannot be copied implicitly
#[component]
fn MyComponent(string: String) -> Element {
rsx! {
button {
// ❌ We are moving the string into the onclick handler which means we can't access it elsewhere
onclick: move |_| {
println!("{string}");
},
"Print hello world"
}
button {
// ❌ Since we already moved the string, we can't move it into the onclick handler again. This will cause a compiler error
onclick: move |_| {
println!("{string}");
},
"Print hello world again"
}
}
}You can fix this issue by either:
- Making your data
CopywithReadSignal:
// `MyComponent` accepts `ReadSignal<String>` which implements `Copy`
#[component]
fn MyComponent(string: ReadSignal<String>) -> Element {
rsx! {
button {
// ✅ Because the `string` signal is `Copy`, we can copy it into the closure while still having access to it elsewhere
onclick: move |_| println!("{}", string),
"Print hello world"
}
button {
// ✅ Since `string` is `Copy`, we can move it into the onclick handler again
onclick: move |_| println!("{}", string),
"Print hello world again"
}
}
}- Calling
cloneon your data before you move it into the closure:
// `MyComponent` accepts a string which doesn't implement `Copy`
#[component]
fn MyComponent(string: String) -> Element {
rsx! {
button {
// ✅ The string only has one owner. We could move it into this closure, but since we want to use the string in other closures later, we will clone it instead
onclick: {
// Clone the string in a new block
let string = string.clone();
// Then move the cloned string into the closure
move |_| println!("{}", string)
},
"Print hello world"
}
button {
// ✅ We don't use the string after this closure, so we can just move it into the closure directly
onclick: move |_| println!("{}", string),
"Print hello world again"
}
}
}Sourcefn onpointerup<__Marker>(
self,
event_handler: impl EventHandlerValue<PointerData, __Marker>,
) -> <Self as AttributeBuilderTarget>::Output
fn onpointerup<__Marker>( self, event_handler: impl EventHandlerValue<PointerData, __Marker>, ) -> <Self as AttributeBuilderTarget>::Output
onpointerup
General Event Handler Information
§Event Handlers
Event Handlers let you react to user input in your application. In Dioxus, event handlers accept a closure that is called when the event occurs:
use dioxus::prelude::*;
fn App() -> Element {
rsx! {
button {
// The `onclick` event accepts a closure with the signature `fn(Event)`
onclick: |event_data| println!("clicked! I got the event data: {event_data:?}"),
"Click me"
}
}
}§Event Lifetimes
Events take a closure with the 'static lifetime. This means that the closure can only access data that either exists for the entire lifetime of the application, or data that you move into the closure.
State in dioxus is copy which makes it very easy to move into 'static closures like event handlers:
let mut count = use_signal(|| 0);
rsx! {
button {
// Since we added the `move` keyword, the closure will move the `count` signal into the closure
onclick: move |_| {
// This will panic because the `count` signal is not in scope
count.set(count() + 1);
},
"Click me"
}
};If you need to access data that is not Copy, you may need to clone the data before you move it into the closure:
// String is not `Copy`
let string = "hello world".to_string();
rsx! {
button {
// The string only has one owner. We could move it into this closure, but since we want to use the string in other closures later, we will clone it instead
onclick: {
// Clone the string in a new block
let string = string.clone();
// Then move the cloned string into the closure
move |_| println!("{}", string)
},
"Print hello world"
}
button {
// We don't use the string after this closure, so we can just move it into the closure directly
onclick: move |_| println!("{}", string),
"Print hello world again"
}
};§Async Event Handlers
In addition to closures that return nothing, you can also use async closures to handle events. If you return an async block from an event handler, dioxus will automatically spawn it:
use dioxus::prelude::*;
fn App() -> Element {
rsx! {
button {
// The `onclick` event can also accept a closure that returns an async block
onclick: move |_| async move {
tokio::time::sleep(std::time::Duration::from_secs(1)).await;
println!("You clicked the button one second ago!");
},
"Click me"
}
}
}§Compiler errors you may run into while using event handlers
function requires argument type to outlive `'static`
Event handler in Dioxus need only access data that can last for the entire lifetime of the application. That generally means data that is moved into the closure. If you get this error, you may have forgotten to add move to your closure.
Broken component:
// We return an Element which can last as long as the component is on the screen
fn App() -> Element {
// Signals are `Copy` which makes them very easy to move into `'static` closures like event handlers
let state = use_signal(|| "hello world".to_string());
rsx! {
button {
// ❌ Without `move`, rust will try to borrow the `state` signal which fails because the state signal is dropped at the end of the function
onclick: |_| {
println!("You clicked the button! The state is: {state}");
},
"Click me"
}
}
// The state signal is dropped here, but the event handler still needs to access it
}Fixed component:
fn App() -> Element {
let state = use_signal(|| "hello world".to_string());
rsx! {
button {
// ✅ The `move` keyword tells rust it can move the `state` signal into the closure. Since the closure owns the signal state, it can read it even after the function returns
onclick: move |_| {
println!("You clicked the button! The state is: {state}");
},
"Click me"
}
}
}use of moved value: `your_value` value used here after move
Data in rust has a single owner. If you run into this error, you have likely tried to move data that isn’t Copy into two different closures. You can fix this issue by making your data Copy or calling clone on it before you move it into the closure.
Broken component:
// `MyComponent` accepts a string which cannot be copied implicitly
#[component]
fn MyComponent(string: String) -> Element {
rsx! {
button {
// ❌ We are moving the string into the onclick handler which means we can't access it elsewhere
onclick: move |_| {
println!("{string}");
},
"Print hello world"
}
button {
// ❌ Since we already moved the string, we can't move it into the onclick handler again. This will cause a compiler error
onclick: move |_| {
println!("{string}");
},
"Print hello world again"
}
}
}You can fix this issue by either:
- Making your data
CopywithReadSignal:
// `MyComponent` accepts `ReadSignal<String>` which implements `Copy`
#[component]
fn MyComponent(string: ReadSignal<String>) -> Element {
rsx! {
button {
// ✅ Because the `string` signal is `Copy`, we can copy it into the closure while still having access to it elsewhere
onclick: move |_| println!("{}", string),
"Print hello world"
}
button {
// ✅ Since `string` is `Copy`, we can move it into the onclick handler again
onclick: move |_| println!("{}", string),
"Print hello world again"
}
}
}- Calling
cloneon your data before you move it into the closure:
// `MyComponent` accepts a string which doesn't implement `Copy`
#[component]
fn MyComponent(string: String) -> Element {
rsx! {
button {
// ✅ The string only has one owner. We could move it into this closure, but since we want to use the string in other closures later, we will clone it instead
onclick: {
// Clone the string in a new block
let string = string.clone();
// Then move the cloned string into the closure
move |_| println!("{}", string)
},
"Print hello world"
}
button {
// ✅ We don't use the string after this closure, so we can just move it into the closure directly
onclick: move |_| println!("{}", string),
"Print hello world again"
}
}
}Sourcefn onpointercancel<__Marker>(
self,
event_handler: impl EventHandlerValue<PointerData, __Marker>,
) -> <Self as AttributeBuilderTarget>::Output
fn onpointercancel<__Marker>( self, event_handler: impl EventHandlerValue<PointerData, __Marker>, ) -> <Self as AttributeBuilderTarget>::Output
onpointercancel
General Event Handler Information
§Event Handlers
Event Handlers let you react to user input in your application. In Dioxus, event handlers accept a closure that is called when the event occurs:
use dioxus::prelude::*;
fn App() -> Element {
rsx! {
button {
// The `onclick` event accepts a closure with the signature `fn(Event)`
onclick: |event_data| println!("clicked! I got the event data: {event_data:?}"),
"Click me"
}
}
}§Event Lifetimes
Events take a closure with the 'static lifetime. This means that the closure can only access data that either exists for the entire lifetime of the application, or data that you move into the closure.
State in dioxus is copy which makes it very easy to move into 'static closures like event handlers:
let mut count = use_signal(|| 0);
rsx! {
button {
// Since we added the `move` keyword, the closure will move the `count` signal into the closure
onclick: move |_| {
// This will panic because the `count` signal is not in scope
count.set(count() + 1);
},
"Click me"
}
};If you need to access data that is not Copy, you may need to clone the data before you move it into the closure:
// String is not `Copy`
let string = "hello world".to_string();
rsx! {
button {
// The string only has one owner. We could move it into this closure, but since we want to use the string in other closures later, we will clone it instead
onclick: {
// Clone the string in a new block
let string = string.clone();
// Then move the cloned string into the closure
move |_| println!("{}", string)
},
"Print hello world"
}
button {
// We don't use the string after this closure, so we can just move it into the closure directly
onclick: move |_| println!("{}", string),
"Print hello world again"
}
};§Async Event Handlers
In addition to closures that return nothing, you can also use async closures to handle events. If you return an async block from an event handler, dioxus will automatically spawn it:
use dioxus::prelude::*;
fn App() -> Element {
rsx! {
button {
// The `onclick` event can also accept a closure that returns an async block
onclick: move |_| async move {
tokio::time::sleep(std::time::Duration::from_secs(1)).await;
println!("You clicked the button one second ago!");
},
"Click me"
}
}
}§Compiler errors you may run into while using event handlers
function requires argument type to outlive `'static`
Event handler in Dioxus need only access data that can last for the entire lifetime of the application. That generally means data that is moved into the closure. If you get this error, you may have forgotten to add move to your closure.
Broken component:
// We return an Element which can last as long as the component is on the screen
fn App() -> Element {
// Signals are `Copy` which makes them very easy to move into `'static` closures like event handlers
let state = use_signal(|| "hello world".to_string());
rsx! {
button {
// ❌ Without `move`, rust will try to borrow the `state` signal which fails because the state signal is dropped at the end of the function
onclick: |_| {
println!("You clicked the button! The state is: {state}");
},
"Click me"
}
}
// The state signal is dropped here, but the event handler still needs to access it
}Fixed component:
fn App() -> Element {
let state = use_signal(|| "hello world".to_string());
rsx! {
button {
// ✅ The `move` keyword tells rust it can move the `state` signal into the closure. Since the closure owns the signal state, it can read it even after the function returns
onclick: move |_| {
println!("You clicked the button! The state is: {state}");
},
"Click me"
}
}
}use of moved value: `your_value` value used here after move
Data in rust has a single owner. If you run into this error, you have likely tried to move data that isn’t Copy into two different closures. You can fix this issue by making your data Copy or calling clone on it before you move it into the closure.
Broken component:
// `MyComponent` accepts a string which cannot be copied implicitly
#[component]
fn MyComponent(string: String) -> Element {
rsx! {
button {
// ❌ We are moving the string into the onclick handler which means we can't access it elsewhere
onclick: move |_| {
println!("{string}");
},
"Print hello world"
}
button {
// ❌ Since we already moved the string, we can't move it into the onclick handler again. This will cause a compiler error
onclick: move |_| {
println!("{string}");
},
"Print hello world again"
}
}
}You can fix this issue by either:
- Making your data
CopywithReadSignal:
// `MyComponent` accepts `ReadSignal<String>` which implements `Copy`
#[component]
fn MyComponent(string: ReadSignal<String>) -> Element {
rsx! {
button {
// ✅ Because the `string` signal is `Copy`, we can copy it into the closure while still having access to it elsewhere
onclick: move |_| println!("{}", string),
"Print hello world"
}
button {
// ✅ Since `string` is `Copy`, we can move it into the onclick handler again
onclick: move |_| println!("{}", string),
"Print hello world again"
}
}
}- Calling
cloneon your data before you move it into the closure:
// `MyComponent` accepts a string which doesn't implement `Copy`
#[component]
fn MyComponent(string: String) -> Element {
rsx! {
button {
// ✅ The string only has one owner. We could move it into this closure, but since we want to use the string in other closures later, we will clone it instead
onclick: {
// Clone the string in a new block
let string = string.clone();
// Then move the cloned string into the closure
move |_| println!("{}", string)
},
"Print hello world"
}
button {
// ✅ We don't use the string after this closure, so we can just move it into the closure directly
onclick: move |_| println!("{}", string),
"Print hello world again"
}
}
}Sourcefn ongotpointercapture<__Marker>(
self,
event_handler: impl EventHandlerValue<PointerData, __Marker>,
) -> <Self as AttributeBuilderTarget>::Output
fn ongotpointercapture<__Marker>( self, event_handler: impl EventHandlerValue<PointerData, __Marker>, ) -> <Self as AttributeBuilderTarget>::Output
ongotpointercapture
General Event Handler Information
§Event Handlers
Event Handlers let you react to user input in your application. In Dioxus, event handlers accept a closure that is called when the event occurs:
use dioxus::prelude::*;
fn App() -> Element {
rsx! {
button {
// The `onclick` event accepts a closure with the signature `fn(Event)`
onclick: |event_data| println!("clicked! I got the event data: {event_data:?}"),
"Click me"
}
}
}§Event Lifetimes
Events take a closure with the 'static lifetime. This means that the closure can only access data that either exists for the entire lifetime of the application, or data that you move into the closure.
State in dioxus is copy which makes it very easy to move into 'static closures like event handlers:
let mut count = use_signal(|| 0);
rsx! {
button {
// Since we added the `move` keyword, the closure will move the `count` signal into the closure
onclick: move |_| {
// This will panic because the `count` signal is not in scope
count.set(count() + 1);
},
"Click me"
}
};If you need to access data that is not Copy, you may need to clone the data before you move it into the closure:
// String is not `Copy`
let string = "hello world".to_string();
rsx! {
button {
// The string only has one owner. We could move it into this closure, but since we want to use the string in other closures later, we will clone it instead
onclick: {
// Clone the string in a new block
let string = string.clone();
// Then move the cloned string into the closure
move |_| println!("{}", string)
},
"Print hello world"
}
button {
// We don't use the string after this closure, so we can just move it into the closure directly
onclick: move |_| println!("{}", string),
"Print hello world again"
}
};§Async Event Handlers
In addition to closures that return nothing, you can also use async closures to handle events. If you return an async block from an event handler, dioxus will automatically spawn it:
use dioxus::prelude::*;
fn App() -> Element {
rsx! {
button {
// The `onclick` event can also accept a closure that returns an async block
onclick: move |_| async move {
tokio::time::sleep(std::time::Duration::from_secs(1)).await;
println!("You clicked the button one second ago!");
},
"Click me"
}
}
}§Compiler errors you may run into while using event handlers
function requires argument type to outlive `'static`
Event handler in Dioxus need only access data that can last for the entire lifetime of the application. That generally means data that is moved into the closure. If you get this error, you may have forgotten to add move to your closure.
Broken component:
// We return an Element which can last as long as the component is on the screen
fn App() -> Element {
// Signals are `Copy` which makes them very easy to move into `'static` closures like event handlers
let state = use_signal(|| "hello world".to_string());
rsx! {
button {
// ❌ Without `move`, rust will try to borrow the `state` signal which fails because the state signal is dropped at the end of the function
onclick: |_| {
println!("You clicked the button! The state is: {state}");
},
"Click me"
}
}
// The state signal is dropped here, but the event handler still needs to access it
}Fixed component:
fn App() -> Element {
let state = use_signal(|| "hello world".to_string());
rsx! {
button {
// ✅ The `move` keyword tells rust it can move the `state` signal into the closure. Since the closure owns the signal state, it can read it even after the function returns
onclick: move |_| {
println!("You clicked the button! The state is: {state}");
},
"Click me"
}
}
}use of moved value: `your_value` value used here after move
Data in rust has a single owner. If you run into this error, you have likely tried to move data that isn’t Copy into two different closures. You can fix this issue by making your data Copy or calling clone on it before you move it into the closure.
Broken component:
// `MyComponent` accepts a string which cannot be copied implicitly
#[component]
fn MyComponent(string: String) -> Element {
rsx! {
button {
// ❌ We are moving the string into the onclick handler which means we can't access it elsewhere
onclick: move |_| {
println!("{string}");
},
"Print hello world"
}
button {
// ❌ Since we already moved the string, we can't move it into the onclick handler again. This will cause a compiler error
onclick: move |_| {
println!("{string}");
},
"Print hello world again"
}
}
}You can fix this issue by either:
- Making your data
CopywithReadSignal:
// `MyComponent` accepts `ReadSignal<String>` which implements `Copy`
#[component]
fn MyComponent(string: ReadSignal<String>) -> Element {
rsx! {
button {
// ✅ Because the `string` signal is `Copy`, we can copy it into the closure while still having access to it elsewhere
onclick: move |_| println!("{}", string),
"Print hello world"
}
button {
// ✅ Since `string` is `Copy`, we can move it into the onclick handler again
onclick: move |_| println!("{}", string),
"Print hello world again"
}
}
}- Calling
cloneon your data before you move it into the closure:
// `MyComponent` accepts a string which doesn't implement `Copy`
#[component]
fn MyComponent(string: String) -> Element {
rsx! {
button {
// ✅ The string only has one owner. We could move it into this closure, but since we want to use the string in other closures later, we will clone it instead
onclick: {
// Clone the string in a new block
let string = string.clone();
// Then move the cloned string into the closure
move |_| println!("{}", string)
},
"Print hello world"
}
button {
// ✅ We don't use the string after this closure, so we can just move it into the closure directly
onclick: move |_| println!("{}", string),
"Print hello world again"
}
}
}Sourcefn onlostpointercapture<__Marker>(
self,
event_handler: impl EventHandlerValue<PointerData, __Marker>,
) -> <Self as AttributeBuilderTarget>::Output
fn onlostpointercapture<__Marker>( self, event_handler: impl EventHandlerValue<PointerData, __Marker>, ) -> <Self as AttributeBuilderTarget>::Output
onlostpointercapture
General Event Handler Information
§Event Handlers
Event Handlers let you react to user input in your application. In Dioxus, event handlers accept a closure that is called when the event occurs:
use dioxus::prelude::*;
fn App() -> Element {
rsx! {
button {
// The `onclick` event accepts a closure with the signature `fn(Event)`
onclick: |event_data| println!("clicked! I got the event data: {event_data:?}"),
"Click me"
}
}
}§Event Lifetimes
Events take a closure with the 'static lifetime. This means that the closure can only access data that either exists for the entire lifetime of the application, or data that you move into the closure.
State in dioxus is copy which makes it very easy to move into 'static closures like event handlers:
let mut count = use_signal(|| 0);
rsx! {
button {
// Since we added the `move` keyword, the closure will move the `count` signal into the closure
onclick: move |_| {
// This will panic because the `count` signal is not in scope
count.set(count() + 1);
},
"Click me"
}
};If you need to access data that is not Copy, you may need to clone the data before you move it into the closure:
// String is not `Copy`
let string = "hello world".to_string();
rsx! {
button {
// The string only has one owner. We could move it into this closure, but since we want to use the string in other closures later, we will clone it instead
onclick: {
// Clone the string in a new block
let string = string.clone();
// Then move the cloned string into the closure
move |_| println!("{}", string)
},
"Print hello world"
}
button {
// We don't use the string after this closure, so we can just move it into the closure directly
onclick: move |_| println!("{}", string),
"Print hello world again"
}
};§Async Event Handlers
In addition to closures that return nothing, you can also use async closures to handle events. If you return an async block from an event handler, dioxus will automatically spawn it:
use dioxus::prelude::*;
fn App() -> Element {
rsx! {
button {
// The `onclick` event can also accept a closure that returns an async block
onclick: move |_| async move {
tokio::time::sleep(std::time::Duration::from_secs(1)).await;
println!("You clicked the button one second ago!");
},
"Click me"
}
}
}§Compiler errors you may run into while using event handlers
function requires argument type to outlive `'static`
Event handler in Dioxus need only access data that can last for the entire lifetime of the application. That generally means data that is moved into the closure. If you get this error, you may have forgotten to add move to your closure.
Broken component:
// We return an Element which can last as long as the component is on the screen
fn App() -> Element {
// Signals are `Copy` which makes them very easy to move into `'static` closures like event handlers
let state = use_signal(|| "hello world".to_string());
rsx! {
button {
// ❌ Without `move`, rust will try to borrow the `state` signal which fails because the state signal is dropped at the end of the function
onclick: |_| {
println!("You clicked the button! The state is: {state}");
},
"Click me"
}
}
// The state signal is dropped here, but the event handler still needs to access it
}Fixed component:
fn App() -> Element {
let state = use_signal(|| "hello world".to_string());
rsx! {
button {
// ✅ The `move` keyword tells rust it can move the `state` signal into the closure. Since the closure owns the signal state, it can read it even after the function returns
onclick: move |_| {
println!("You clicked the button! The state is: {state}");
},
"Click me"
}
}
}use of moved value: `your_value` value used here after move
Data in rust has a single owner. If you run into this error, you have likely tried to move data that isn’t Copy into two different closures. You can fix this issue by making your data Copy or calling clone on it before you move it into the closure.
Broken component:
// `MyComponent` accepts a string which cannot be copied implicitly
#[component]
fn MyComponent(string: String) -> Element {
rsx! {
button {
// ❌ We are moving the string into the onclick handler which means we can't access it elsewhere
onclick: move |_| {
println!("{string}");
},
"Print hello world"
}
button {
// ❌ Since we already moved the string, we can't move it into the onclick handler again. This will cause a compiler error
onclick: move |_| {
println!("{string}");
},
"Print hello world again"
}
}
}You can fix this issue by either:
- Making your data
CopywithReadSignal:
// `MyComponent` accepts `ReadSignal<String>` which implements `Copy`
#[component]
fn MyComponent(string: ReadSignal<String>) -> Element {
rsx! {
button {
// ✅ Because the `string` signal is `Copy`, we can copy it into the closure while still having access to it elsewhere
onclick: move |_| println!("{}", string),
"Print hello world"
}
button {
// ✅ Since `string` is `Copy`, we can move it into the onclick handler again
onclick: move |_| println!("{}", string),
"Print hello world again"
}
}
}- Calling
cloneon your data before you move it into the closure:
// `MyComponent` accepts a string which doesn't implement `Copy`
#[component]
fn MyComponent(string: String) -> Element {
rsx! {
button {
// ✅ The string only has one owner. We could move it into this closure, but since we want to use the string in other closures later, we will clone it instead
onclick: {
// Clone the string in a new block
let string = string.clone();
// Then move the cloned string into the closure
move |_| println!("{}", string)
},
"Print hello world"
}
button {
// ✅ We don't use the string after this closure, so we can just move it into the closure directly
onclick: move |_| println!("{}", string),
"Print hello world again"
}
}
}Sourcefn onpointerenter<__Marker>(
self,
event_handler: impl EventHandlerValue<PointerData, __Marker>,
) -> <Self as AttributeBuilderTarget>::Output
fn onpointerenter<__Marker>( self, event_handler: impl EventHandlerValue<PointerData, __Marker>, ) -> <Self as AttributeBuilderTarget>::Output
onpointerenter
General Event Handler Information
§Event Handlers
Event Handlers let you react to user input in your application. In Dioxus, event handlers accept a closure that is called when the event occurs:
use dioxus::prelude::*;
fn App() -> Element {
rsx! {
button {
// The `onclick` event accepts a closure with the signature `fn(Event)`
onclick: |event_data| println!("clicked! I got the event data: {event_data:?}"),
"Click me"
}
}
}§Event Lifetimes
Events take a closure with the 'static lifetime. This means that the closure can only access data that either exists for the entire lifetime of the application, or data that you move into the closure.
State in dioxus is copy which makes it very easy to move into 'static closures like event handlers:
let mut count = use_signal(|| 0);
rsx! {
button {
// Since we added the `move` keyword, the closure will move the `count` signal into the closure
onclick: move |_| {
// This will panic because the `count` signal is not in scope
count.set(count() + 1);
},
"Click me"
}
};If you need to access data that is not Copy, you may need to clone the data before you move it into the closure:
// String is not `Copy`
let string = "hello world".to_string();
rsx! {
button {
// The string only has one owner. We could move it into this closure, but since we want to use the string in other closures later, we will clone it instead
onclick: {
// Clone the string in a new block
let string = string.clone();
// Then move the cloned string into the closure
move |_| println!("{}", string)
},
"Print hello world"
}
button {
// We don't use the string after this closure, so we can just move it into the closure directly
onclick: move |_| println!("{}", string),
"Print hello world again"
}
};§Async Event Handlers
In addition to closures that return nothing, you can also use async closures to handle events. If you return an async block from an event handler, dioxus will automatically spawn it:
use dioxus::prelude::*;
fn App() -> Element {
rsx! {
button {
// The `onclick` event can also accept a closure that returns an async block
onclick: move |_| async move {
tokio::time::sleep(std::time::Duration::from_secs(1)).await;
println!("You clicked the button one second ago!");
},
"Click me"
}
}
}§Compiler errors you may run into while using event handlers
function requires argument type to outlive `'static`
Event handler in Dioxus need only access data that can last for the entire lifetime of the application. That generally means data that is moved into the closure. If you get this error, you may have forgotten to add move to your closure.
Broken component:
// We return an Element which can last as long as the component is on the screen
fn App() -> Element {
// Signals are `Copy` which makes them very easy to move into `'static` closures like event handlers
let state = use_signal(|| "hello world".to_string());
rsx! {
button {
// ❌ Without `move`, rust will try to borrow the `state` signal which fails because the state signal is dropped at the end of the function
onclick: |_| {
println!("You clicked the button! The state is: {state}");
},
"Click me"
}
}
// The state signal is dropped here, but the event handler still needs to access it
}Fixed component:
fn App() -> Element {
let state = use_signal(|| "hello world".to_string());
rsx! {
button {
// ✅ The `move` keyword tells rust it can move the `state` signal into the closure. Since the closure owns the signal state, it can read it even after the function returns
onclick: move |_| {
println!("You clicked the button! The state is: {state}");
},
"Click me"
}
}
}use of moved value: `your_value` value used here after move
Data in rust has a single owner. If you run into this error, you have likely tried to move data that isn’t Copy into two different closures. You can fix this issue by making your data Copy or calling clone on it before you move it into the closure.
Broken component:
// `MyComponent` accepts a string which cannot be copied implicitly
#[component]
fn MyComponent(string: String) -> Element {
rsx! {
button {
// ❌ We are moving the string into the onclick handler which means we can't access it elsewhere
onclick: move |_| {
println!("{string}");
},
"Print hello world"
}
button {
// ❌ Since we already moved the string, we can't move it into the onclick handler again. This will cause a compiler error
onclick: move |_| {
println!("{string}");
},
"Print hello world again"
}
}
}You can fix this issue by either:
- Making your data
CopywithReadSignal:
// `MyComponent` accepts `ReadSignal<String>` which implements `Copy`
#[component]
fn MyComponent(string: ReadSignal<String>) -> Element {
rsx! {
button {
// ✅ Because the `string` signal is `Copy`, we can copy it into the closure while still having access to it elsewhere
onclick: move |_| println!("{}", string),
"Print hello world"
}
button {
// ✅ Since `string` is `Copy`, we can move it into the onclick handler again
onclick: move |_| println!("{}", string),
"Print hello world again"
}
}
}- Calling
cloneon your data before you move it into the closure:
// `MyComponent` accepts a string which doesn't implement `Copy`
#[component]
fn MyComponent(string: String) -> Element {
rsx! {
button {
// ✅ The string only has one owner. We could move it into this closure, but since we want to use the string in other closures later, we will clone it instead
onclick: {
// Clone the string in a new block
let string = string.clone();
// Then move the cloned string into the closure
move |_| println!("{}", string)
},
"Print hello world"
}
button {
// ✅ We don't use the string after this closure, so we can just move it into the closure directly
onclick: move |_| println!("{}", string),
"Print hello world again"
}
}
}Sourcefn onpointerleave<__Marker>(
self,
event_handler: impl EventHandlerValue<PointerData, __Marker>,
) -> <Self as AttributeBuilderTarget>::Output
fn onpointerleave<__Marker>( self, event_handler: impl EventHandlerValue<PointerData, __Marker>, ) -> <Self as AttributeBuilderTarget>::Output
onpointerleave
General Event Handler Information
§Event Handlers
Event Handlers let you react to user input in your application. In Dioxus, event handlers accept a closure that is called when the event occurs:
use dioxus::prelude::*;
fn App() -> Element {
rsx! {
button {
// The `onclick` event accepts a closure with the signature `fn(Event)`
onclick: |event_data| println!("clicked! I got the event data: {event_data:?}"),
"Click me"
}
}
}§Event Lifetimes
Events take a closure with the 'static lifetime. This means that the closure can only access data that either exists for the entire lifetime of the application, or data that you move into the closure.
State in dioxus is copy which makes it very easy to move into 'static closures like event handlers:
let mut count = use_signal(|| 0);
rsx! {
button {
// Since we added the `move` keyword, the closure will move the `count` signal into the closure
onclick: move |_| {
// This will panic because the `count` signal is not in scope
count.set(count() + 1);
},
"Click me"
}
};If you need to access data that is not Copy, you may need to clone the data before you move it into the closure:
// String is not `Copy`
let string = "hello world".to_string();
rsx! {
button {
// The string only has one owner. We could move it into this closure, but since we want to use the string in other closures later, we will clone it instead
onclick: {
// Clone the string in a new block
let string = string.clone();
// Then move the cloned string into the closure
move |_| println!("{}", string)
},
"Print hello world"
}
button {
// We don't use the string after this closure, so we can just move it into the closure directly
onclick: move |_| println!("{}", string),
"Print hello world again"
}
};§Async Event Handlers
In addition to closures that return nothing, you can also use async closures to handle events. If you return an async block from an event handler, dioxus will automatically spawn it:
use dioxus::prelude::*;
fn App() -> Element {
rsx! {
button {
// The `onclick` event can also accept a closure that returns an async block
onclick: move |_| async move {
tokio::time::sleep(std::time::Duration::from_secs(1)).await;
println!("You clicked the button one second ago!");
},
"Click me"
}
}
}§Compiler errors you may run into while using event handlers
function requires argument type to outlive `'static`
Event handler in Dioxus need only access data that can last for the entire lifetime of the application. That generally means data that is moved into the closure. If you get this error, you may have forgotten to add move to your closure.
Broken component:
// We return an Element which can last as long as the component is on the screen
fn App() -> Element {
// Signals are `Copy` which makes them very easy to move into `'static` closures like event handlers
let state = use_signal(|| "hello world".to_string());
rsx! {
button {
// ❌ Without `move`, rust will try to borrow the `state` signal which fails because the state signal is dropped at the end of the function
onclick: |_| {
println!("You clicked the button! The state is: {state}");
},
"Click me"
}
}
// The state signal is dropped here, but the event handler still needs to access it
}Fixed component:
fn App() -> Element {
let state = use_signal(|| "hello world".to_string());
rsx! {
button {
// ✅ The `move` keyword tells rust it can move the `state` signal into the closure. Since the closure owns the signal state, it can read it even after the function returns
onclick: move |_| {
println!("You clicked the button! The state is: {state}");
},
"Click me"
}
}
}use of moved value: `your_value` value used here after move
Data in rust has a single owner. If you run into this error, you have likely tried to move data that isn’t Copy into two different closures. You can fix this issue by making your data Copy or calling clone on it before you move it into the closure.
Broken component:
// `MyComponent` accepts a string which cannot be copied implicitly
#[component]
fn MyComponent(string: String) -> Element {
rsx! {
button {
// ❌ We are moving the string into the onclick handler which means we can't access it elsewhere
onclick: move |_| {
println!("{string}");
},
"Print hello world"
}
button {
// ❌ Since we already moved the string, we can't move it into the onclick handler again. This will cause a compiler error
onclick: move |_| {
println!("{string}");
},
"Print hello world again"
}
}
}You can fix this issue by either:
- Making your data
CopywithReadSignal:
// `MyComponent` accepts `ReadSignal<String>` which implements `Copy`
#[component]
fn MyComponent(string: ReadSignal<String>) -> Element {
rsx! {
button {
// ✅ Because the `string` signal is `Copy`, we can copy it into the closure while still having access to it elsewhere
onclick: move |_| println!("{}", string),
"Print hello world"
}
button {
// ✅ Since `string` is `Copy`, we can move it into the onclick handler again
onclick: move |_| println!("{}", string),
"Print hello world again"
}
}
}- Calling
cloneon your data before you move it into the closure:
// `MyComponent` accepts a string which doesn't implement `Copy`
#[component]
fn MyComponent(string: String) -> Element {
rsx! {
button {
// ✅ The string only has one owner. We could move it into this closure, but since we want to use the string in other closures later, we will clone it instead
onclick: {
// Clone the string in a new block
let string = string.clone();
// Then move the cloned string into the closure
move |_| println!("{}", string)
},
"Print hello world"
}
button {
// ✅ We don't use the string after this closure, so we can just move it into the closure directly
onclick: move |_| println!("{}", string),
"Print hello world again"
}
}
}Sourcefn onpointerover<__Marker>(
self,
event_handler: impl EventHandlerValue<PointerData, __Marker>,
) -> <Self as AttributeBuilderTarget>::Output
fn onpointerover<__Marker>( self, event_handler: impl EventHandlerValue<PointerData, __Marker>, ) -> <Self as AttributeBuilderTarget>::Output
onpointerover
General Event Handler Information
§Event Handlers
Event Handlers let you react to user input in your application. In Dioxus, event handlers accept a closure that is called when the event occurs:
use dioxus::prelude::*;
fn App() -> Element {
rsx! {
button {
// The `onclick` event accepts a closure with the signature `fn(Event)`
onclick: |event_data| println!("clicked! I got the event data: {event_data:?}"),
"Click me"
}
}
}§Event Lifetimes
Events take a closure with the 'static lifetime. This means that the closure can only access data that either exists for the entire lifetime of the application, or data that you move into the closure.
State in dioxus is copy which makes it very easy to move into 'static closures like event handlers:
let mut count = use_signal(|| 0);
rsx! {
button {
// Since we added the `move` keyword, the closure will move the `count` signal into the closure
onclick: move |_| {
// This will panic because the `count` signal is not in scope
count.set(count() + 1);
},
"Click me"
}
};If you need to access data that is not Copy, you may need to clone the data before you move it into the closure:
// String is not `Copy`
let string = "hello world".to_string();
rsx! {
button {
// The string only has one owner. We could move it into this closure, but since we want to use the string in other closures later, we will clone it instead
onclick: {
// Clone the string in a new block
let string = string.clone();
// Then move the cloned string into the closure
move |_| println!("{}", string)
},
"Print hello world"
}
button {
// We don't use the string after this closure, so we can just move it into the closure directly
onclick: move |_| println!("{}", string),
"Print hello world again"
}
};§Async Event Handlers
In addition to closures that return nothing, you can also use async closures to handle events. If you return an async block from an event handler, dioxus will automatically spawn it:
use dioxus::prelude::*;
fn App() -> Element {
rsx! {
button {
// The `onclick` event can also accept a closure that returns an async block
onclick: move |_| async move {
tokio::time::sleep(std::time::Duration::from_secs(1)).await;
println!("You clicked the button one second ago!");
},
"Click me"
}
}
}§Compiler errors you may run into while using event handlers
function requires argument type to outlive `'static`
Event handler in Dioxus need only access data that can last for the entire lifetime of the application. That generally means data that is moved into the closure. If you get this error, you may have forgotten to add move to your closure.
Broken component:
// We return an Element which can last as long as the component is on the screen
fn App() -> Element {
// Signals are `Copy` which makes them very easy to move into `'static` closures like event handlers
let state = use_signal(|| "hello world".to_string());
rsx! {
button {
// ❌ Without `move`, rust will try to borrow the `state` signal which fails because the state signal is dropped at the end of the function
onclick: |_| {
println!("You clicked the button! The state is: {state}");
},
"Click me"
}
}
// The state signal is dropped here, but the event handler still needs to access it
}Fixed component:
fn App() -> Element {
let state = use_signal(|| "hello world".to_string());
rsx! {
button {
// ✅ The `move` keyword tells rust it can move the `state` signal into the closure. Since the closure owns the signal state, it can read it even after the function returns
onclick: move |_| {
println!("You clicked the button! The state is: {state}");
},
"Click me"
}
}
}use of moved value: `your_value` value used here after move
Data in rust has a single owner. If you run into this error, you have likely tried to move data that isn’t Copy into two different closures. You can fix this issue by making your data Copy or calling clone on it before you move it into the closure.
Broken component:
// `MyComponent` accepts a string which cannot be copied implicitly
#[component]
fn MyComponent(string: String) -> Element {
rsx! {
button {
// ❌ We are moving the string into the onclick handler which means we can't access it elsewhere
onclick: move |_| {
println!("{string}");
},
"Print hello world"
}
button {
// ❌ Since we already moved the string, we can't move it into the onclick handler again. This will cause a compiler error
onclick: move |_| {
println!("{string}");
},
"Print hello world again"
}
}
}You can fix this issue by either:
- Making your data
CopywithReadSignal:
// `MyComponent` accepts `ReadSignal<String>` which implements `Copy`
#[component]
fn MyComponent(string: ReadSignal<String>) -> Element {
rsx! {
button {
// ✅ Because the `string` signal is `Copy`, we can copy it into the closure while still having access to it elsewhere
onclick: move |_| println!("{}", string),
"Print hello world"
}
button {
// ✅ Since `string` is `Copy`, we can move it into the onclick handler again
onclick: move |_| println!("{}", string),
"Print hello world again"
}
}
}- Calling
cloneon your data before you move it into the closure:
// `MyComponent` accepts a string which doesn't implement `Copy`
#[component]
fn MyComponent(string: String) -> Element {
rsx! {
button {
// ✅ The string only has one owner. We could move it into this closure, but since we want to use the string in other closures later, we will clone it instead
onclick: {
// Clone the string in a new block
let string = string.clone();
// Then move the cloned string into the closure
move |_| println!("{}", string)
},
"Print hello world"
}
button {
// ✅ We don't use the string after this closure, so we can just move it into the closure directly
onclick: move |_| println!("{}", string),
"Print hello world again"
}
}
}Sourcefn onpointerout<__Marker>(
self,
event_handler: impl EventHandlerValue<PointerData, __Marker>,
) -> <Self as AttributeBuilderTarget>::Output
fn onpointerout<__Marker>( self, event_handler: impl EventHandlerValue<PointerData, __Marker>, ) -> <Self as AttributeBuilderTarget>::Output
onpointerout
General Event Handler Information
§Event Handlers
Event Handlers let you react to user input in your application. In Dioxus, event handlers accept a closure that is called when the event occurs:
use dioxus::prelude::*;
fn App() -> Element {
rsx! {
button {
// The `onclick` event accepts a closure with the signature `fn(Event)`
onclick: |event_data| println!("clicked! I got the event data: {event_data:?}"),
"Click me"
}
}
}§Event Lifetimes
Events take a closure with the 'static lifetime. This means that the closure can only access data that either exists for the entire lifetime of the application, or data that you move into the closure.
State in dioxus is copy which makes it very easy to move into 'static closures like event handlers:
let mut count = use_signal(|| 0);
rsx! {
button {
// Since we added the `move` keyword, the closure will move the `count` signal into the closure
onclick: move |_| {
// This will panic because the `count` signal is not in scope
count.set(count() + 1);
},
"Click me"
}
};If you need to access data that is not Copy, you may need to clone the data before you move it into the closure:
// String is not `Copy`
let string = "hello world".to_string();
rsx! {
button {
// The string only has one owner. We could move it into this closure, but since we want to use the string in other closures later, we will clone it instead
onclick: {
// Clone the string in a new block
let string = string.clone();
// Then move the cloned string into the closure
move |_| println!("{}", string)
},
"Print hello world"
}
button {
// We don't use the string after this closure, so we can just move it into the closure directly
onclick: move |_| println!("{}", string),
"Print hello world again"
}
};§Async Event Handlers
In addition to closures that return nothing, you can also use async closures to handle events. If you return an async block from an event handler, dioxus will automatically spawn it:
use dioxus::prelude::*;
fn App() -> Element {
rsx! {
button {
// The `onclick` event can also accept a closure that returns an async block
onclick: move |_| async move {
tokio::time::sleep(std::time::Duration::from_secs(1)).await;
println!("You clicked the button one second ago!");
},
"Click me"
}
}
}§Compiler errors you may run into while using event handlers
function requires argument type to outlive `'static`
Event handler in Dioxus need only access data that can last for the entire lifetime of the application. That generally means data that is moved into the closure. If you get this error, you may have forgotten to add move to your closure.
Broken component:
// We return an Element which can last as long as the component is on the screen
fn App() -> Element {
// Signals are `Copy` which makes them very easy to move into `'static` closures like event handlers
let state = use_signal(|| "hello world".to_string());
rsx! {
button {
// ❌ Without `move`, rust will try to borrow the `state` signal which fails because the state signal is dropped at the end of the function
onclick: |_| {
println!("You clicked the button! The state is: {state}");
},
"Click me"
}
}
// The state signal is dropped here, but the event handler still needs to access it
}Fixed component:
fn App() -> Element {
let state = use_signal(|| "hello world".to_string());
rsx! {
button {
// ✅ The `move` keyword tells rust it can move the `state` signal into the closure. Since the closure owns the signal state, it can read it even after the function returns
onclick: move |_| {
println!("You clicked the button! The state is: {state}");
},
"Click me"
}
}
}use of moved value: `your_value` value used here after move
Data in rust has a single owner. If you run into this error, you have likely tried to move data that isn’t Copy into two different closures. You can fix this issue by making your data Copy or calling clone on it before you move it into the closure.
Broken component:
// `MyComponent` accepts a string which cannot be copied implicitly
#[component]
fn MyComponent(string: String) -> Element {
rsx! {
button {
// ❌ We are moving the string into the onclick handler which means we can't access it elsewhere
onclick: move |_| {
println!("{string}");
},
"Print hello world"
}
button {
// ❌ Since we already moved the string, we can't move it into the onclick handler again. This will cause a compiler error
onclick: move |_| {
println!("{string}");
},
"Print hello world again"
}
}
}You can fix this issue by either:
- Making your data
CopywithReadSignal:
// `MyComponent` accepts `ReadSignal<String>` which implements `Copy`
#[component]
fn MyComponent(string: ReadSignal<String>) -> Element {
rsx! {
button {
// ✅ Because the `string` signal is `Copy`, we can copy it into the closure while still having access to it elsewhere
onclick: move |_| println!("{}", string),
"Print hello world"
}
button {
// ✅ Since `string` is `Copy`, we can move it into the onclick handler again
onclick: move |_| println!("{}", string),
"Print hello world again"
}
}
}- Calling
cloneon your data before you move it into the closure:
// `MyComponent` accepts a string which doesn't implement `Copy`
#[component]
fn MyComponent(string: String) -> Element {
rsx! {
button {
// ✅ The string only has one owner. We could move it into this closure, but since we want to use the string in other closures later, we will clone it instead
onclick: {
// Clone the string in a new block
let string = string.clone();
// Then move the cloned string into the closure
move |_| println!("{}", string)
},
"Print hello world"
}
button {
// ✅ We don't use the string after this closure, so we can just move it into the closure directly
onclick: move |_| println!("{}", string),
"Print hello world again"
}
}
}Sourcefn onauxclick<__Marker>(
self,
event_handler: impl EventHandlerValue<PointerData, __Marker>,
) -> <Self as AttributeBuilderTarget>::Output
fn onauxclick<__Marker>( self, event_handler: impl EventHandlerValue<PointerData, __Marker>, ) -> <Self as AttributeBuilderTarget>::Output
onauxclick
General Event Handler Information
§Event Handlers
Event Handlers let you react to user input in your application. In Dioxus, event handlers accept a closure that is called when the event occurs:
use dioxus::prelude::*;
fn App() -> Element {
rsx! {
button {
// The `onclick` event accepts a closure with the signature `fn(Event)`
onclick: |event_data| println!("clicked! I got the event data: {event_data:?}"),
"Click me"
}
}
}§Event Lifetimes
Events take a closure with the 'static lifetime. This means that the closure can only access data that either exists for the entire lifetime of the application, or data that you move into the closure.
State in dioxus is copy which makes it very easy to move into 'static closures like event handlers:
let mut count = use_signal(|| 0);
rsx! {
button {
// Since we added the `move` keyword, the closure will move the `count` signal into the closure
onclick: move |_| {
// This will panic because the `count` signal is not in scope
count.set(count() + 1);
},
"Click me"
}
};If you need to access data that is not Copy, you may need to clone the data before you move it into the closure:
// String is not `Copy`
let string = "hello world".to_string();
rsx! {
button {
// The string only has one owner. We could move it into this closure, but since we want to use the string in other closures later, we will clone it instead
onclick: {
// Clone the string in a new block
let string = string.clone();
// Then move the cloned string into the closure
move |_| println!("{}", string)
},
"Print hello world"
}
button {
// We don't use the string after this closure, so we can just move it into the closure directly
onclick: move |_| println!("{}", string),
"Print hello world again"
}
};§Async Event Handlers
In addition to closures that return nothing, you can also use async closures to handle events. If you return an async block from an event handler, dioxus will automatically spawn it:
use dioxus::prelude::*;
fn App() -> Element {
rsx! {
button {
// The `onclick` event can also accept a closure that returns an async block
onclick: move |_| async move {
tokio::time::sleep(std::time::Duration::from_secs(1)).await;
println!("You clicked the button one second ago!");
},
"Click me"
}
}
}§Compiler errors you may run into while using event handlers
function requires argument type to outlive `'static`
Event handler in Dioxus need only access data that can last for the entire lifetime of the application. That generally means data that is moved into the closure. If you get this error, you may have forgotten to add move to your closure.
Broken component:
// We return an Element which can last as long as the component is on the screen
fn App() -> Element {
// Signals are `Copy` which makes them very easy to move into `'static` closures like event handlers
let state = use_signal(|| "hello world".to_string());
rsx! {
button {
// ❌ Without `move`, rust will try to borrow the `state` signal which fails because the state signal is dropped at the end of the function
onclick: |_| {
println!("You clicked the button! The state is: {state}");
},
"Click me"
}
}
// The state signal is dropped here, but the event handler still needs to access it
}Fixed component:
fn App() -> Element {
let state = use_signal(|| "hello world".to_string());
rsx! {
button {
// ✅ The `move` keyword tells rust it can move the `state` signal into the closure. Since the closure owns the signal state, it can read it even after the function returns
onclick: move |_| {
println!("You clicked the button! The state is: {state}");
},
"Click me"
}
}
}use of moved value: `your_value` value used here after move
Data in rust has a single owner. If you run into this error, you have likely tried to move data that isn’t Copy into two different closures. You can fix this issue by making your data Copy or calling clone on it before you move it into the closure.
Broken component:
// `MyComponent` accepts a string which cannot be copied implicitly
#[component]
fn MyComponent(string: String) -> Element {
rsx! {
button {
// ❌ We are moving the string into the onclick handler which means we can't access it elsewhere
onclick: move |_| {
println!("{string}");
},
"Print hello world"
}
button {
// ❌ Since we already moved the string, we can't move it into the onclick handler again. This will cause a compiler error
onclick: move |_| {
println!("{string}");
},
"Print hello world again"
}
}
}You can fix this issue by either:
- Making your data
CopywithReadSignal:
// `MyComponent` accepts `ReadSignal<String>` which implements `Copy`
#[component]
fn MyComponent(string: ReadSignal<String>) -> Element {
rsx! {
button {
// ✅ Because the `string` signal is `Copy`, we can copy it into the closure while still having access to it elsewhere
onclick: move |_| println!("{}", string),
"Print hello world"
}
button {
// ✅ Since `string` is `Copy`, we can move it into the onclick handler again
onclick: move |_| println!("{}", string),
"Print hello world again"
}
}
}- Calling
cloneon your data before you move it into the closure:
// `MyComponent` accepts a string which doesn't implement `Copy`
#[component]
fn MyComponent(string: String) -> Element {
rsx! {
button {
// ✅ The string only has one owner. We could move it into this closure, but since we want to use the string in other closures later, we will clone it instead
onclick: {
// Clone the string in a new block
let string = string.clone();
// Then move the cloned string into the closure
move |_| println!("{}", string)
},
"Print hello world"
}
button {
// ✅ We don't use the string after this closure, so we can just move it into the closure directly
onclick: move |_| println!("{}", string),
"Print hello world again"
}
}
}Sourcefn onresize<__Marker>(
self,
event_handler: impl EventHandlerValue<ResizeData, __Marker>,
) -> <Self as AttributeBuilderTarget>::Output
fn onresize<__Marker>( self, event_handler: impl EventHandlerValue<ResizeData, __Marker>, ) -> <Self as AttributeBuilderTarget>::Output
onresize
General Event Handler Information
§Event Handlers
Event Handlers let you react to user input in your application. In Dioxus, event handlers accept a closure that is called when the event occurs:
use dioxus::prelude::*;
fn App() -> Element {
rsx! {
button {
// The `onclick` event accepts a closure with the signature `fn(Event)`
onclick: |event_data| println!("clicked! I got the event data: {event_data:?}"),
"Click me"
}
}
}§Event Lifetimes
Events take a closure with the 'static lifetime. This means that the closure can only access data that either exists for the entire lifetime of the application, or data that you move into the closure.
State in dioxus is copy which makes it very easy to move into 'static closures like event handlers:
let mut count = use_signal(|| 0);
rsx! {
button {
// Since we added the `move` keyword, the closure will move the `count` signal into the closure
onclick: move |_| {
// This will panic because the `count` signal is not in scope
count.set(count() + 1);
},
"Click me"
}
};If you need to access data that is not Copy, you may need to clone the data before you move it into the closure:
// String is not `Copy`
let string = "hello world".to_string();
rsx! {
button {
// The string only has one owner. We could move it into this closure, but since we want to use the string in other closures later, we will clone it instead
onclick: {
// Clone the string in a new block
let string = string.clone();
// Then move the cloned string into the closure
move |_| println!("{}", string)
},
"Print hello world"
}
button {
// We don't use the string after this closure, so we can just move it into the closure directly
onclick: move |_| println!("{}", string),
"Print hello world again"
}
};§Async Event Handlers
In addition to closures that return nothing, you can also use async closures to handle events. If you return an async block from an event handler, dioxus will automatically spawn it:
use dioxus::prelude::*;
fn App() -> Element {
rsx! {
button {
// The `onclick` event can also accept a closure that returns an async block
onclick: move |_| async move {
tokio::time::sleep(std::time::Duration::from_secs(1)).await;
println!("You clicked the button one second ago!");
},
"Click me"
}
}
}§Compiler errors you may run into while using event handlers
function requires argument type to outlive `'static`
Event handler in Dioxus need only access data that can last for the entire lifetime of the application. That generally means data that is moved into the closure. If you get this error, you may have forgotten to add move to your closure.
Broken component:
// We return an Element which can last as long as the component is on the screen
fn App() -> Element {
// Signals are `Copy` which makes them very easy to move into `'static` closures like event handlers
let state = use_signal(|| "hello world".to_string());
rsx! {
button {
// ❌ Without `move`, rust will try to borrow the `state` signal which fails because the state signal is dropped at the end of the function
onclick: |_| {
println!("You clicked the button! The state is: {state}");
},
"Click me"
}
}
// The state signal is dropped here, but the event handler still needs to access it
}Fixed component:
fn App() -> Element {
let state = use_signal(|| "hello world".to_string());
rsx! {
button {
// ✅ The `move` keyword tells rust it can move the `state` signal into the closure. Since the closure owns the signal state, it can read it even after the function returns
onclick: move |_| {
println!("You clicked the button! The state is: {state}");
},
"Click me"
}
}
}use of moved value: `your_value` value used here after move
Data in rust has a single owner. If you run into this error, you have likely tried to move data that isn’t Copy into two different closures. You can fix this issue by making your data Copy or calling clone on it before you move it into the closure.
Broken component:
// `MyComponent` accepts a string which cannot be copied implicitly
#[component]
fn MyComponent(string: String) -> Element {
rsx! {
button {
// ❌ We are moving the string into the onclick handler which means we can't access it elsewhere
onclick: move |_| {
println!("{string}");
},
"Print hello world"
}
button {
// ❌ Since we already moved the string, we can't move it into the onclick handler again. This will cause a compiler error
onclick: move |_| {
println!("{string}");
},
"Print hello world again"
}
}
}You can fix this issue by either:
- Making your data
CopywithReadSignal:
// `MyComponent` accepts `ReadSignal<String>` which implements `Copy`
#[component]
fn MyComponent(string: ReadSignal<String>) -> Element {
rsx! {
button {
// ✅ Because the `string` signal is `Copy`, we can copy it into the closure while still having access to it elsewhere
onclick: move |_| println!("{}", string),
"Print hello world"
}
button {
// ✅ Since `string` is `Copy`, we can move it into the onclick handler again
onclick: move |_| println!("{}", string),
"Print hello world again"
}
}
}- Calling
cloneon your data before you move it into the closure:
// `MyComponent` accepts a string which doesn't implement `Copy`
#[component]
fn MyComponent(string: String) -> Element {
rsx! {
button {
// ✅ The string only has one owner. We could move it into this closure, but since we want to use the string in other closures later, we will clone it instead
onclick: {
// Clone the string in a new block
let string = string.clone();
// Then move the cloned string into the closure
move |_| println!("{}", string)
},
"Print hello world"
}
button {
// ✅ We don't use the string after this closure, so we can just move it into the closure directly
onclick: move |_| println!("{}", string),
"Print hello world again"
}
}
}Sourcefn onscroll<__Marker>(
self,
event_handler: impl EventHandlerValue<ScrollData, __Marker>,
) -> <Self as AttributeBuilderTarget>::Output
fn onscroll<__Marker>( self, event_handler: impl EventHandlerValue<ScrollData, __Marker>, ) -> <Self as AttributeBuilderTarget>::Output
onscroll
General Event Handler Information
§Event Handlers
Event Handlers let you react to user input in your application. In Dioxus, event handlers accept a closure that is called when the event occurs:
use dioxus::prelude::*;
fn App() -> Element {
rsx! {
button {
// The `onclick` event accepts a closure with the signature `fn(Event)`
onclick: |event_data| println!("clicked! I got the event data: {event_data:?}"),
"Click me"
}
}
}§Event Lifetimes
Events take a closure with the 'static lifetime. This means that the closure can only access data that either exists for the entire lifetime of the application, or data that you move into the closure.
State in dioxus is copy which makes it very easy to move into 'static closures like event handlers:
let mut count = use_signal(|| 0);
rsx! {
button {
// Since we added the `move` keyword, the closure will move the `count` signal into the closure
onclick: move |_| {
// This will panic because the `count` signal is not in scope
count.set(count() + 1);
},
"Click me"
}
};If you need to access data that is not Copy, you may need to clone the data before you move it into the closure:
// String is not `Copy`
let string = "hello world".to_string();
rsx! {
button {
// The string only has one owner. We could move it into this closure, but since we want to use the string in other closures later, we will clone it instead
onclick: {
// Clone the string in a new block
let string = string.clone();
// Then move the cloned string into the closure
move |_| println!("{}", string)
},
"Print hello world"
}
button {
// We don't use the string after this closure, so we can just move it into the closure directly
onclick: move |_| println!("{}", string),
"Print hello world again"
}
};§Async Event Handlers
In addition to closures that return nothing, you can also use async closures to handle events. If you return an async block from an event handler, dioxus will automatically spawn it:
use dioxus::prelude::*;
fn App() -> Element {
rsx! {
button {
// The `onclick` event can also accept a closure that returns an async block
onclick: move |_| async move {
tokio::time::sleep(std::time::Duration::from_secs(1)).await;
println!("You clicked the button one second ago!");
},
"Click me"
}
}
}§Compiler errors you may run into while using event handlers
function requires argument type to outlive `'static`
Event handler in Dioxus need only access data that can last for the entire lifetime of the application. That generally means data that is moved into the closure. If you get this error, you may have forgotten to add move to your closure.
Broken component:
// We return an Element which can last as long as the component is on the screen
fn App() -> Element {
// Signals are `Copy` which makes them very easy to move into `'static` closures like event handlers
let state = use_signal(|| "hello world".to_string());
rsx! {
button {
// ❌ Without `move`, rust will try to borrow the `state` signal which fails because the state signal is dropped at the end of the function
onclick: |_| {
println!("You clicked the button! The state is: {state}");
},
"Click me"
}
}
// The state signal is dropped here, but the event handler still needs to access it
}Fixed component:
fn App() -> Element {
let state = use_signal(|| "hello world".to_string());
rsx! {
button {
// ✅ The `move` keyword tells rust it can move the `state` signal into the closure. Since the closure owns the signal state, it can read it even after the function returns
onclick: move |_| {
println!("You clicked the button! The state is: {state}");
},
"Click me"
}
}
}use of moved value: `your_value` value used here after move
Data in rust has a single owner. If you run into this error, you have likely tried to move data that isn’t Copy into two different closures. You can fix this issue by making your data Copy or calling clone on it before you move it into the closure.
Broken component:
// `MyComponent` accepts a string which cannot be copied implicitly
#[component]
fn MyComponent(string: String) -> Element {
rsx! {
button {
// ❌ We are moving the string into the onclick handler which means we can't access it elsewhere
onclick: move |_| {
println!("{string}");
},
"Print hello world"
}
button {
// ❌ Since we already moved the string, we can't move it into the onclick handler again. This will cause a compiler error
onclick: move |_| {
println!("{string}");
},
"Print hello world again"
}
}
}You can fix this issue by either:
- Making your data
CopywithReadSignal:
// `MyComponent` accepts `ReadSignal<String>` which implements `Copy`
#[component]
fn MyComponent(string: ReadSignal<String>) -> Element {
rsx! {
button {
// ✅ Because the `string` signal is `Copy`, we can copy it into the closure while still having access to it elsewhere
onclick: move |_| println!("{}", string),
"Print hello world"
}
button {
// ✅ Since `string` is `Copy`, we can move it into the onclick handler again
onclick: move |_| println!("{}", string),
"Print hello world again"
}
}
}- Calling
cloneon your data before you move it into the closure:
// `MyComponent` accepts a string which doesn't implement `Copy`
#[component]
fn MyComponent(string: String) -> Element {
rsx! {
button {
// ✅ The string only has one owner. We could move it into this closure, but since we want to use the string in other closures later, we will clone it instead
onclick: {
// Clone the string in a new block
let string = string.clone();
// Then move the cloned string into the closure
move |_| println!("{}", string)
},
"Print hello world"
}
button {
// ✅ We don't use the string after this closure, so we can just move it into the closure directly
onclick: move |_| println!("{}", string),
"Print hello world again"
}
}
}Sourcefn onscrollend<__Marker>(
self,
event_handler: impl EventHandlerValue<ScrollData, __Marker>,
) -> <Self as AttributeBuilderTarget>::Output
fn onscrollend<__Marker>( self, event_handler: impl EventHandlerValue<ScrollData, __Marker>, ) -> <Self as AttributeBuilderTarget>::Output
onscrollend
General Event Handler Information
§Event Handlers
Event Handlers let you react to user input in your application. In Dioxus, event handlers accept a closure that is called when the event occurs:
use dioxus::prelude::*;
fn App() -> Element {
rsx! {
button {
// The `onclick` event accepts a closure with the signature `fn(Event)`
onclick: |event_data| println!("clicked! I got the event data: {event_data:?}"),
"Click me"
}
}
}§Event Lifetimes
Events take a closure with the 'static lifetime. This means that the closure can only access data that either exists for the entire lifetime of the application, or data that you move into the closure.
State in dioxus is copy which makes it very easy to move into 'static closures like event handlers:
let mut count = use_signal(|| 0);
rsx! {
button {
// Since we added the `move` keyword, the closure will move the `count` signal into the closure
onclick: move |_| {
// This will panic because the `count` signal is not in scope
count.set(count() + 1);
},
"Click me"
}
};If you need to access data that is not Copy, you may need to clone the data before you move it into the closure:
// String is not `Copy`
let string = "hello world".to_string();
rsx! {
button {
// The string only has one owner. We could move it into this closure, but since we want to use the string in other closures later, we will clone it instead
onclick: {
// Clone the string in a new block
let string = string.clone();
// Then move the cloned string into the closure
move |_| println!("{}", string)
},
"Print hello world"
}
button {
// We don't use the string after this closure, so we can just move it into the closure directly
onclick: move |_| println!("{}", string),
"Print hello world again"
}
};§Async Event Handlers
In addition to closures that return nothing, you can also use async closures to handle events. If you return an async block from an event handler, dioxus will automatically spawn it:
use dioxus::prelude::*;
fn App() -> Element {
rsx! {
button {
// The `onclick` event can also accept a closure that returns an async block
onclick: move |_| async move {
tokio::time::sleep(std::time::Duration::from_secs(1)).await;
println!("You clicked the button one second ago!");
},
"Click me"
}
}
}§Compiler errors you may run into while using event handlers
function requires argument type to outlive `'static`
Event handler in Dioxus need only access data that can last for the entire lifetime of the application. That generally means data that is moved into the closure. If you get this error, you may have forgotten to add move to your closure.
Broken component:
// We return an Element which can last as long as the component is on the screen
fn App() -> Element {
// Signals are `Copy` which makes them very easy to move into `'static` closures like event handlers
let state = use_signal(|| "hello world".to_string());
rsx! {
button {
// ❌ Without `move`, rust will try to borrow the `state` signal which fails because the state signal is dropped at the end of the function
onclick: |_| {
println!("You clicked the button! The state is: {state}");
},
"Click me"
}
}
// The state signal is dropped here, but the event handler still needs to access it
}Fixed component:
fn App() -> Element {
let state = use_signal(|| "hello world".to_string());
rsx! {
button {
// ✅ The `move` keyword tells rust it can move the `state` signal into the closure. Since the closure owns the signal state, it can read it even after the function returns
onclick: move |_| {
println!("You clicked the button! The state is: {state}");
},
"Click me"
}
}
}use of moved value: `your_value` value used here after move
Data in rust has a single owner. If you run into this error, you have likely tried to move data that isn’t Copy into two different closures. You can fix this issue by making your data Copy or calling clone on it before you move it into the closure.
Broken component:
// `MyComponent` accepts a string which cannot be copied implicitly
#[component]
fn MyComponent(string: String) -> Element {
rsx! {
button {
// ❌ We are moving the string into the onclick handler which means we can't access it elsewhere
onclick: move |_| {
println!("{string}");
},
"Print hello world"
}
button {
// ❌ Since we already moved the string, we can't move it into the onclick handler again. This will cause a compiler error
onclick: move |_| {
println!("{string}");
},
"Print hello world again"
}
}
}You can fix this issue by either:
- Making your data
CopywithReadSignal:
// `MyComponent` accepts `ReadSignal<String>` which implements `Copy`
#[component]
fn MyComponent(string: ReadSignal<String>) -> Element {
rsx! {
button {
// ✅ Because the `string` signal is `Copy`, we can copy it into the closure while still having access to it elsewhere
onclick: move |_| println!("{}", string),
"Print hello world"
}
button {
// ✅ Since `string` is `Copy`, we can move it into the onclick handler again
onclick: move |_| println!("{}", string),
"Print hello world again"
}
}
}- Calling
cloneon your data before you move it into the closure:
// `MyComponent` accepts a string which doesn't implement `Copy`
#[component]
fn MyComponent(string: String) -> Element {
rsx! {
button {
// ✅ The string only has one owner. We could move it into this closure, but since we want to use the string in other closures later, we will clone it instead
onclick: {
// Clone the string in a new block
let string = string.clone();
// Then move the cloned string into the closure
move |_| println!("{}", string)
},
"Print hello world"
}
button {
// ✅ We don't use the string after this closure, so we can just move it into the closure directly
onclick: move |_| println!("{}", string),
"Print hello world again"
}
}
}Sourcefn onselect<__Marker>(
self,
event_handler: impl EventHandlerValue<SelectionData, __Marker>,
) -> <Self as AttributeBuilderTarget>::Output
fn onselect<__Marker>( self, event_handler: impl EventHandlerValue<SelectionData, __Marker>, ) -> <Self as AttributeBuilderTarget>::Output
onselect
General Event Handler Information
§Event Handlers
Event Handlers let you react to user input in your application. In Dioxus, event handlers accept a closure that is called when the event occurs:
use dioxus::prelude::*;
fn App() -> Element {
rsx! {
button {
// The `onclick` event accepts a closure with the signature `fn(Event)`
onclick: |event_data| println!("clicked! I got the event data: {event_data:?}"),
"Click me"
}
}
}§Event Lifetimes
Events take a closure with the 'static lifetime. This means that the closure can only access data that either exists for the entire lifetime of the application, or data that you move into the closure.
State in dioxus is copy which makes it very easy to move into 'static closures like event handlers:
let mut count = use_signal(|| 0);
rsx! {
button {
// Since we added the `move` keyword, the closure will move the `count` signal into the closure
onclick: move |_| {
// This will panic because the `count` signal is not in scope
count.set(count() + 1);
},
"Click me"
}
};If you need to access data that is not Copy, you may need to clone the data before you move it into the closure:
// String is not `Copy`
let string = "hello world".to_string();
rsx! {
button {
// The string only has one owner. We could move it into this closure, but since we want to use the string in other closures later, we will clone it instead
onclick: {
// Clone the string in a new block
let string = string.clone();
// Then move the cloned string into the closure
move |_| println!("{}", string)
},
"Print hello world"
}
button {
// We don't use the string after this closure, so we can just move it into the closure directly
onclick: move |_| println!("{}", string),
"Print hello world again"
}
};§Async Event Handlers
In addition to closures that return nothing, you can also use async closures to handle events. If you return an async block from an event handler, dioxus will automatically spawn it:
use dioxus::prelude::*;
fn App() -> Element {
rsx! {
button {
// The `onclick` event can also accept a closure that returns an async block
onclick: move |_| async move {
tokio::time::sleep(std::time::Duration::from_secs(1)).await;
println!("You clicked the button one second ago!");
},
"Click me"
}
}
}§Compiler errors you may run into while using event handlers
function requires argument type to outlive `'static`
Event handler in Dioxus need only access data that can last for the entire lifetime of the application. That generally means data that is moved into the closure. If you get this error, you may have forgotten to add move to your closure.
Broken component:
// We return an Element which can last as long as the component is on the screen
fn App() -> Element {
// Signals are `Copy` which makes them very easy to move into `'static` closures like event handlers
let state = use_signal(|| "hello world".to_string());
rsx! {
button {
// ❌ Without `move`, rust will try to borrow the `state` signal which fails because the state signal is dropped at the end of the function
onclick: |_| {
println!("You clicked the button! The state is: {state}");
},
"Click me"
}
}
// The state signal is dropped here, but the event handler still needs to access it
}Fixed component:
fn App() -> Element {
let state = use_signal(|| "hello world".to_string());
rsx! {
button {
// ✅ The `move` keyword tells rust it can move the `state` signal into the closure. Since the closure owns the signal state, it can read it even after the function returns
onclick: move |_| {
println!("You clicked the button! The state is: {state}");
},
"Click me"
}
}
}use of moved value: `your_value` value used here after move
Data in rust has a single owner. If you run into this error, you have likely tried to move data that isn’t Copy into two different closures. You can fix this issue by making your data Copy or calling clone on it before you move it into the closure.
Broken component:
// `MyComponent` accepts a string which cannot be copied implicitly
#[component]
fn MyComponent(string: String) -> Element {
rsx! {
button {
// ❌ We are moving the string into the onclick handler which means we can't access it elsewhere
onclick: move |_| {
println!("{string}");
},
"Print hello world"
}
button {
// ❌ Since we already moved the string, we can't move it into the onclick handler again. This will cause a compiler error
onclick: move |_| {
println!("{string}");
},
"Print hello world again"
}
}
}You can fix this issue by either:
- Making your data
CopywithReadSignal:
// `MyComponent` accepts `ReadSignal<String>` which implements `Copy`
#[component]
fn MyComponent(string: ReadSignal<String>) -> Element {
rsx! {
button {
// ✅ Because the `string` signal is `Copy`, we can copy it into the closure while still having access to it elsewhere
onclick: move |_| println!("{}", string),
"Print hello world"
}
button {
// ✅ Since `string` is `Copy`, we can move it into the onclick handler again
onclick: move |_| println!("{}", string),
"Print hello world again"
}
}
}- Calling
cloneon your data before you move it into the closure:
// `MyComponent` accepts a string which doesn't implement `Copy`
#[component]
fn MyComponent(string: String) -> Element {
rsx! {
button {
// ✅ The string only has one owner. We could move it into this closure, but since we want to use the string in other closures later, we will clone it instead
onclick: {
// Clone the string in a new block
let string = string.clone();
// Then move the cloned string into the closure
move |_| println!("{}", string)
},
"Print hello world"
}
button {
// ✅ We don't use the string after this closure, so we can just move it into the closure directly
onclick: move |_| println!("{}", string),
"Print hello world again"
}
}
}Sourcefn onselectstart<__Marker>(
self,
event_handler: impl EventHandlerValue<SelectionData, __Marker>,
) -> <Self as AttributeBuilderTarget>::Output
fn onselectstart<__Marker>( self, event_handler: impl EventHandlerValue<SelectionData, __Marker>, ) -> <Self as AttributeBuilderTarget>::Output
onselectstart
General Event Handler Information
§Event Handlers
Event Handlers let you react to user input in your application. In Dioxus, event handlers accept a closure that is called when the event occurs:
use dioxus::prelude::*;
fn App() -> Element {
rsx! {
button {
// The `onclick` event accepts a closure with the signature `fn(Event)`
onclick: |event_data| println!("clicked! I got the event data: {event_data:?}"),
"Click me"
}
}
}§Event Lifetimes
Events take a closure with the 'static lifetime. This means that the closure can only access data that either exists for the entire lifetime of the application, or data that you move into the closure.
State in dioxus is copy which makes it very easy to move into 'static closures like event handlers:
let mut count = use_signal(|| 0);
rsx! {
button {
// Since we added the `move` keyword, the closure will move the `count` signal into the closure
onclick: move |_| {
// This will panic because the `count` signal is not in scope
count.set(count() + 1);
},
"Click me"
}
};If you need to access data that is not Copy, you may need to clone the data before you move it into the closure:
// String is not `Copy`
let string = "hello world".to_string();
rsx! {
button {
// The string only has one owner. We could move it into this closure, but since we want to use the string in other closures later, we will clone it instead
onclick: {
// Clone the string in a new block
let string = string.clone();
// Then move the cloned string into the closure
move |_| println!("{}", string)
},
"Print hello world"
}
button {
// We don't use the string after this closure, so we can just move it into the closure directly
onclick: move |_| println!("{}", string),
"Print hello world again"
}
};§Async Event Handlers
In addition to closures that return nothing, you can also use async closures to handle events. If you return an async block from an event handler, dioxus will automatically spawn it:
use dioxus::prelude::*;
fn App() -> Element {
rsx! {
button {
// The `onclick` event can also accept a closure that returns an async block
onclick: move |_| async move {
tokio::time::sleep(std::time::Duration::from_secs(1)).await;
println!("You clicked the button one second ago!");
},
"Click me"
}
}
}§Compiler errors you may run into while using event handlers
function requires argument type to outlive `'static`
Event handler in Dioxus need only access data that can last for the entire lifetime of the application. That generally means data that is moved into the closure. If you get this error, you may have forgotten to add move to your closure.
Broken component:
// We return an Element which can last as long as the component is on the screen
fn App() -> Element {
// Signals are `Copy` which makes them very easy to move into `'static` closures like event handlers
let state = use_signal(|| "hello world".to_string());
rsx! {
button {
// ❌ Without `move`, rust will try to borrow the `state` signal which fails because the state signal is dropped at the end of the function
onclick: |_| {
println!("You clicked the button! The state is: {state}");
},
"Click me"
}
}
// The state signal is dropped here, but the event handler still needs to access it
}Fixed component:
fn App() -> Element {
let state = use_signal(|| "hello world".to_string());
rsx! {
button {
// ✅ The `move` keyword tells rust it can move the `state` signal into the closure. Since the closure owns the signal state, it can read it even after the function returns
onclick: move |_| {
println!("You clicked the button! The state is: {state}");
},
"Click me"
}
}
}use of moved value: `your_value` value used here after move
Data in rust has a single owner. If you run into this error, you have likely tried to move data that isn’t Copy into two different closures. You can fix this issue by making your data Copy or calling clone on it before you move it into the closure.
Broken component:
// `MyComponent` accepts a string which cannot be copied implicitly
#[component]
fn MyComponent(string: String) -> Element {
rsx! {
button {
// ❌ We are moving the string into the onclick handler which means we can't access it elsewhere
onclick: move |_| {
println!("{string}");
},
"Print hello world"
}
button {
// ❌ Since we already moved the string, we can't move it into the onclick handler again. This will cause a compiler error
onclick: move |_| {
println!("{string}");
},
"Print hello world again"
}
}
}You can fix this issue by either:
- Making your data
CopywithReadSignal:
// `MyComponent` accepts `ReadSignal<String>` which implements `Copy`
#[component]
fn MyComponent(string: ReadSignal<String>) -> Element {
rsx! {
button {
// ✅ Because the `string` signal is `Copy`, we can copy it into the closure while still having access to it elsewhere
onclick: move |_| println!("{}", string),
"Print hello world"
}
button {
// ✅ Since `string` is `Copy`, we can move it into the onclick handler again
onclick: move |_| println!("{}", string),
"Print hello world again"
}
}
}- Calling
cloneon your data before you move it into the closure:
// `MyComponent` accepts a string which doesn't implement `Copy`
#[component]
fn MyComponent(string: String) -> Element {
rsx! {
button {
// ✅ The string only has one owner. We could move it into this closure, but since we want to use the string in other closures later, we will clone it instead
onclick: {
// Clone the string in a new block
let string = string.clone();
// Then move the cloned string into the closure
move |_| println!("{}", string)
},
"Print hello world"
}
button {
// ✅ We don't use the string after this closure, so we can just move it into the closure directly
onclick: move |_| println!("{}", string),
"Print hello world again"
}
}
}Sourcefn onselectionchange<__Marker>(
self,
event_handler: impl EventHandlerValue<SelectionData, __Marker>,
) -> <Self as AttributeBuilderTarget>::Output
fn onselectionchange<__Marker>( self, event_handler: impl EventHandlerValue<SelectionData, __Marker>, ) -> <Self as AttributeBuilderTarget>::Output
onselectionchange
General Event Handler Information
§Event Handlers
Event Handlers let you react to user input in your application. In Dioxus, event handlers accept a closure that is called when the event occurs:
use dioxus::prelude::*;
fn App() -> Element {
rsx! {
button {
// The `onclick` event accepts a closure with the signature `fn(Event)`
onclick: |event_data| println!("clicked! I got the event data: {event_data:?}"),
"Click me"
}
}
}§Event Lifetimes
Events take a closure with the 'static lifetime. This means that the closure can only access data that either exists for the entire lifetime of the application, or data that you move into the closure.
State in dioxus is copy which makes it very easy to move into 'static closures like event handlers:
let mut count = use_signal(|| 0);
rsx! {
button {
// Since we added the `move` keyword, the closure will move the `count` signal into the closure
onclick: move |_| {
// This will panic because the `count` signal is not in scope
count.set(count() + 1);
},
"Click me"
}
};If you need to access data that is not Copy, you may need to clone the data before you move it into the closure:
// String is not `Copy`
let string = "hello world".to_string();
rsx! {
button {
// The string only has one owner. We could move it into this closure, but since we want to use the string in other closures later, we will clone it instead
onclick: {
// Clone the string in a new block
let string = string.clone();
// Then move the cloned string into the closure
move |_| println!("{}", string)
},
"Print hello world"
}
button {
// We don't use the string after this closure, so we can just move it into the closure directly
onclick: move |_| println!("{}", string),
"Print hello world again"
}
};§Async Event Handlers
In addition to closures that return nothing, you can also use async closures to handle events. If you return an async block from an event handler, dioxus will automatically spawn it:
use dioxus::prelude::*;
fn App() -> Element {
rsx! {
button {
// The `onclick` event can also accept a closure that returns an async block
onclick: move |_| async move {
tokio::time::sleep(std::time::Duration::from_secs(1)).await;
println!("You clicked the button one second ago!");
},
"Click me"
}
}
}§Compiler errors you may run into while using event handlers
function requires argument type to outlive `'static`
Event handler in Dioxus need only access data that can last for the entire lifetime of the application. That generally means data that is moved into the closure. If you get this error, you may have forgotten to add move to your closure.
Broken component:
// We return an Element which can last as long as the component is on the screen
fn App() -> Element {
// Signals are `Copy` which makes them very easy to move into `'static` closures like event handlers
let state = use_signal(|| "hello world".to_string());
rsx! {
button {
// ❌ Without `move`, rust will try to borrow the `state` signal which fails because the state signal is dropped at the end of the function
onclick: |_| {
println!("You clicked the button! The state is: {state}");
},
"Click me"
}
}
// The state signal is dropped here, but the event handler still needs to access it
}Fixed component:
fn App() -> Element {
let state = use_signal(|| "hello world".to_string());
rsx! {
button {
// ✅ The `move` keyword tells rust it can move the `state` signal into the closure. Since the closure owns the signal state, it can read it even after the function returns
onclick: move |_| {
println!("You clicked the button! The state is: {state}");
},
"Click me"
}
}
}use of moved value: `your_value` value used here after move
Data in rust has a single owner. If you run into this error, you have likely tried to move data that isn’t Copy into two different closures. You can fix this issue by making your data Copy or calling clone on it before you move it into the closure.
Broken component:
// `MyComponent` accepts a string which cannot be copied implicitly
#[component]
fn MyComponent(string: String) -> Element {
rsx! {
button {
// ❌ We are moving the string into the onclick handler which means we can't access it elsewhere
onclick: move |_| {
println!("{string}");
},
"Print hello world"
}
button {
// ❌ Since we already moved the string, we can't move it into the onclick handler again. This will cause a compiler error
onclick: move |_| {
println!("{string}");
},
"Print hello world again"
}
}
}You can fix this issue by either:
- Making your data
CopywithReadSignal:
// `MyComponent` accepts `ReadSignal<String>` which implements `Copy`
#[component]
fn MyComponent(string: ReadSignal<String>) -> Element {
rsx! {
button {
// ✅ Because the `string` signal is `Copy`, we can copy it into the closure while still having access to it elsewhere
onclick: move |_| println!("{}", string),
"Print hello world"
}
button {
// ✅ Since `string` is `Copy`, we can move it into the onclick handler again
onclick: move |_| println!("{}", string),
"Print hello world again"
}
}
}- Calling
cloneon your data before you move it into the closure:
// `MyComponent` accepts a string which doesn't implement `Copy`
#[component]
fn MyComponent(string: String) -> Element {
rsx! {
button {
// ✅ The string only has one owner. We could move it into this closure, but since we want to use the string in other closures later, we will clone it instead
onclick: {
// Clone the string in a new block
let string = string.clone();
// Then move the cloned string into the closure
move |_| println!("{}", string)
},
"Print hello world"
}
button {
// ✅ We don't use the string after this closure, so we can just move it into the closure directly
onclick: move |_| println!("{}", string),
"Print hello world again"
}
}
}Sourcefn ontoggle<__Marker>(
self,
event_handler: impl EventHandlerValue<ToggleData, __Marker>,
) -> <Self as AttributeBuilderTarget>::Output
fn ontoggle<__Marker>( self, event_handler: impl EventHandlerValue<ToggleData, __Marker>, ) -> <Self as AttributeBuilderTarget>::Output
ontoggle
General Event Handler Information
§Event Handlers
Event Handlers let you react to user input in your application. In Dioxus, event handlers accept a closure that is called when the event occurs:
use dioxus::prelude::*;
fn App() -> Element {
rsx! {
button {
// The `onclick` event accepts a closure with the signature `fn(Event)`
onclick: |event_data| println!("clicked! I got the event data: {event_data:?}"),
"Click me"
}
}
}§Event Lifetimes
Events take a closure with the 'static lifetime. This means that the closure can only access data that either exists for the entire lifetime of the application, or data that you move into the closure.
State in dioxus is copy which makes it very easy to move into 'static closures like event handlers:
let mut count = use_signal(|| 0);
rsx! {
button {
// Since we added the `move` keyword, the closure will move the `count` signal into the closure
onclick: move |_| {
// This will panic because the `count` signal is not in scope
count.set(count() + 1);
},
"Click me"
}
};If you need to access data that is not Copy, you may need to clone the data before you move it into the closure:
// String is not `Copy`
let string = "hello world".to_string();
rsx! {
button {
// The string only has one owner. We could move it into this closure, but since we want to use the string in other closures later, we will clone it instead
onclick: {
// Clone the string in a new block
let string = string.clone();
// Then move the cloned string into the closure
move |_| println!("{}", string)
},
"Print hello world"
}
button {
// We don't use the string after this closure, so we can just move it into the closure directly
onclick: move |_| println!("{}", string),
"Print hello world again"
}
};§Async Event Handlers
In addition to closures that return nothing, you can also use async closures to handle events. If you return an async block from an event handler, dioxus will automatically spawn it:
use dioxus::prelude::*;
fn App() -> Element {
rsx! {
button {
// The `onclick` event can also accept a closure that returns an async block
onclick: move |_| async move {
tokio::time::sleep(std::time::Duration::from_secs(1)).await;
println!("You clicked the button one second ago!");
},
"Click me"
}
}
}§Compiler errors you may run into while using event handlers
function requires argument type to outlive `'static`
Event handler in Dioxus need only access data that can last for the entire lifetime of the application. That generally means data that is moved into the closure. If you get this error, you may have forgotten to add move to your closure.
Broken component:
// We return an Element which can last as long as the component is on the screen
fn App() -> Element {
// Signals are `Copy` which makes them very easy to move into `'static` closures like event handlers
let state = use_signal(|| "hello world".to_string());
rsx! {
button {
// ❌ Without `move`, rust will try to borrow the `state` signal which fails because the state signal is dropped at the end of the function
onclick: |_| {
println!("You clicked the button! The state is: {state}");
},
"Click me"
}
}
// The state signal is dropped here, but the event handler still needs to access it
}Fixed component:
fn App() -> Element {
let state = use_signal(|| "hello world".to_string());
rsx! {
button {
// ✅ The `move` keyword tells rust it can move the `state` signal into the closure. Since the closure owns the signal state, it can read it even after the function returns
onclick: move |_| {
println!("You clicked the button! The state is: {state}");
},
"Click me"
}
}
}use of moved value: `your_value` value used here after move
Data in rust has a single owner. If you run into this error, you have likely tried to move data that isn’t Copy into two different closures. You can fix this issue by making your data Copy or calling clone on it before you move it into the closure.
Broken component:
// `MyComponent` accepts a string which cannot be copied implicitly
#[component]
fn MyComponent(string: String) -> Element {
rsx! {
button {
// ❌ We are moving the string into the onclick handler which means we can't access it elsewhere
onclick: move |_| {
println!("{string}");
},
"Print hello world"
}
button {
// ❌ Since we already moved the string, we can't move it into the onclick handler again. This will cause a compiler error
onclick: move |_| {
println!("{string}");
},
"Print hello world again"
}
}
}You can fix this issue by either:
- Making your data
CopywithReadSignal:
// `MyComponent` accepts `ReadSignal<String>` which implements `Copy`
#[component]
fn MyComponent(string: ReadSignal<String>) -> Element {
rsx! {
button {
// ✅ Because the `string` signal is `Copy`, we can copy it into the closure while still having access to it elsewhere
onclick: move |_| println!("{}", string),
"Print hello world"
}
button {
// ✅ Since `string` is `Copy`, we can move it into the onclick handler again
onclick: move |_| println!("{}", string),
"Print hello world again"
}
}
}- Calling
cloneon your data before you move it into the closure:
// `MyComponent` accepts a string which doesn't implement `Copy`
#[component]
fn MyComponent(string: String) -> Element {
rsx! {
button {
// ✅ The string only has one owner. We could move it into this closure, but since we want to use the string in other closures later, we will clone it instead
onclick: {
// Clone the string in a new block
let string = string.clone();
// Then move the cloned string into the closure
move |_| println!("{}", string)
},
"Print hello world"
}
button {
// ✅ We don't use the string after this closure, so we can just move it into the closure directly
onclick: move |_| println!("{}", string),
"Print hello world again"
}
}
}Sourcefn onbeforetoggle<__Marker>(
self,
event_handler: impl EventHandlerValue<ToggleData, __Marker>,
) -> <Self as AttributeBuilderTarget>::Output
fn onbeforetoggle<__Marker>( self, event_handler: impl EventHandlerValue<ToggleData, __Marker>, ) -> <Self as AttributeBuilderTarget>::Output
onbeforetoggle
General Event Handler Information
§Event Handlers
Event Handlers let you react to user input in your application. In Dioxus, event handlers accept a closure that is called when the event occurs:
use dioxus::prelude::*;
fn App() -> Element {
rsx! {
button {
// The `onclick` event accepts a closure with the signature `fn(Event)`
onclick: |event_data| println!("clicked! I got the event data: {event_data:?}"),
"Click me"
}
}
}§Event Lifetimes
Events take a closure with the 'static lifetime. This means that the closure can only access data that either exists for the entire lifetime of the application, or data that you move into the closure.
State in dioxus is copy which makes it very easy to move into 'static closures like event handlers:
let mut count = use_signal(|| 0);
rsx! {
button {
// Since we added the `move` keyword, the closure will move the `count` signal into the closure
onclick: move |_| {
// This will panic because the `count` signal is not in scope
count.set(count() + 1);
},
"Click me"
}
};If you need to access data that is not Copy, you may need to clone the data before you move it into the closure:
// String is not `Copy`
let string = "hello world".to_string();
rsx! {
button {
// The string only has one owner. We could move it into this closure, but since we want to use the string in other closures later, we will clone it instead
onclick: {
// Clone the string in a new block
let string = string.clone();
// Then move the cloned string into the closure
move |_| println!("{}", string)
},
"Print hello world"
}
button {
// We don't use the string after this closure, so we can just move it into the closure directly
onclick: move |_| println!("{}", string),
"Print hello world again"
}
};§Async Event Handlers
In addition to closures that return nothing, you can also use async closures to handle events. If you return an async block from an event handler, dioxus will automatically spawn it:
use dioxus::prelude::*;
fn App() -> Element {
rsx! {
button {
// The `onclick` event can also accept a closure that returns an async block
onclick: move |_| async move {
tokio::time::sleep(std::time::Duration::from_secs(1)).await;
println!("You clicked the button one second ago!");
},
"Click me"
}
}
}§Compiler errors you may run into while using event handlers
function requires argument type to outlive `'static`
Event handler in Dioxus need only access data that can last for the entire lifetime of the application. That generally means data that is moved into the closure. If you get this error, you may have forgotten to add move to your closure.
Broken component:
// We return an Element which can last as long as the component is on the screen
fn App() -> Element {
// Signals are `Copy` which makes them very easy to move into `'static` closures like event handlers
let state = use_signal(|| "hello world".to_string());
rsx! {
button {
// ❌ Without `move`, rust will try to borrow the `state` signal which fails because the state signal is dropped at the end of the function
onclick: |_| {
println!("You clicked the button! The state is: {state}");
},
"Click me"
}
}
// The state signal is dropped here, but the event handler still needs to access it
}Fixed component:
fn App() -> Element {
let state = use_signal(|| "hello world".to_string());
rsx! {
button {
// ✅ The `move` keyword tells rust it can move the `state` signal into the closure. Since the closure owns the signal state, it can read it even after the function returns
onclick: move |_| {
println!("You clicked the button! The state is: {state}");
},
"Click me"
}
}
}use of moved value: `your_value` value used here after move
Data in rust has a single owner. If you run into this error, you have likely tried to move data that isn’t Copy into two different closures. You can fix this issue by making your data Copy or calling clone on it before you move it into the closure.
Broken component:
// `MyComponent` accepts a string which cannot be copied implicitly
#[component]
fn MyComponent(string: String) -> Element {
rsx! {
button {
// ❌ We are moving the string into the onclick handler which means we can't access it elsewhere
onclick: move |_| {
println!("{string}");
},
"Print hello world"
}
button {
// ❌ Since we already moved the string, we can't move it into the onclick handler again. This will cause a compiler error
onclick: move |_| {
println!("{string}");
},
"Print hello world again"
}
}
}You can fix this issue by either:
- Making your data
CopywithReadSignal:
// `MyComponent` accepts `ReadSignal<String>` which implements `Copy`
#[component]
fn MyComponent(string: ReadSignal<String>) -> Element {
rsx! {
button {
// ✅ Because the `string` signal is `Copy`, we can copy it into the closure while still having access to it elsewhere
onclick: move |_| println!("{}", string),
"Print hello world"
}
button {
// ✅ Since `string` is `Copy`, we can move it into the onclick handler again
onclick: move |_| println!("{}", string),
"Print hello world again"
}
}
}- Calling
cloneon your data before you move it into the closure:
// `MyComponent` accepts a string which doesn't implement `Copy`
#[component]
fn MyComponent(string: String) -> Element {
rsx! {
button {
// ✅ The string only has one owner. We could move it into this closure, but since we want to use the string in other closures later, we will clone it instead
onclick: {
// Clone the string in a new block
let string = string.clone();
// Then move the cloned string into the closure
move |_| println!("{}", string)
},
"Print hello world"
}
button {
// ✅ We don't use the string after this closure, so we can just move it into the closure directly
onclick: move |_| println!("{}", string),
"Print hello world again"
}
}
}Sourcefn ontouchstart<__Marker>(
self,
event_handler: impl EventHandlerValue<TouchData, __Marker>,
) -> <Self as AttributeBuilderTarget>::Output
fn ontouchstart<__Marker>( self, event_handler: impl EventHandlerValue<TouchData, __Marker>, ) -> <Self as AttributeBuilderTarget>::Output
ontouchstart
General Event Handler Information
§Event Handlers
Event Handlers let you react to user input in your application. In Dioxus, event handlers accept a closure that is called when the event occurs:
use dioxus::prelude::*;
fn App() -> Element {
rsx! {
button {
// The `onclick` event accepts a closure with the signature `fn(Event)`
onclick: |event_data| println!("clicked! I got the event data: {event_data:?}"),
"Click me"
}
}
}§Event Lifetimes
Events take a closure with the 'static lifetime. This means that the closure can only access data that either exists for the entire lifetime of the application, or data that you move into the closure.
State in dioxus is copy which makes it very easy to move into 'static closures like event handlers:
let mut count = use_signal(|| 0);
rsx! {
button {
// Since we added the `move` keyword, the closure will move the `count` signal into the closure
onclick: move |_| {
// This will panic because the `count` signal is not in scope
count.set(count() + 1);
},
"Click me"
}
};If you need to access data that is not Copy, you may need to clone the data before you move it into the closure:
// String is not `Copy`
let string = "hello world".to_string();
rsx! {
button {
// The string only has one owner. We could move it into this closure, but since we want to use the string in other closures later, we will clone it instead
onclick: {
// Clone the string in a new block
let string = string.clone();
// Then move the cloned string into the closure
move |_| println!("{}", string)
},
"Print hello world"
}
button {
// We don't use the string after this closure, so we can just move it into the closure directly
onclick: move |_| println!("{}", string),
"Print hello world again"
}
};§Async Event Handlers
In addition to closures that return nothing, you can also use async closures to handle events. If you return an async block from an event handler, dioxus will automatically spawn it:
use dioxus::prelude::*;
fn App() -> Element {
rsx! {
button {
// The `onclick` event can also accept a closure that returns an async block
onclick: move |_| async move {
tokio::time::sleep(std::time::Duration::from_secs(1)).await;
println!("You clicked the button one second ago!");
},
"Click me"
}
}
}§Compiler errors you may run into while using event handlers
function requires argument type to outlive `'static`
Event handler in Dioxus need only access data that can last for the entire lifetime of the application. That generally means data that is moved into the closure. If you get this error, you may have forgotten to add move to your closure.
Broken component:
// We return an Element which can last as long as the component is on the screen
fn App() -> Element {
// Signals are `Copy` which makes them very easy to move into `'static` closures like event handlers
let state = use_signal(|| "hello world".to_string());
rsx! {
button {
// ❌ Without `move`, rust will try to borrow the `state` signal which fails because the state signal is dropped at the end of the function
onclick: |_| {
println!("You clicked the button! The state is: {state}");
},
"Click me"
}
}
// The state signal is dropped here, but the event handler still needs to access it
}Fixed component:
fn App() -> Element {
let state = use_signal(|| "hello world".to_string());
rsx! {
button {
// ✅ The `move` keyword tells rust it can move the `state` signal into the closure. Since the closure owns the signal state, it can read it even after the function returns
onclick: move |_| {
println!("You clicked the button! The state is: {state}");
},
"Click me"
}
}
}use of moved value: `your_value` value used here after move
Data in rust has a single owner. If you run into this error, you have likely tried to move data that isn’t Copy into two different closures. You can fix this issue by making your data Copy or calling clone on it before you move it into the closure.
Broken component:
// `MyComponent` accepts a string which cannot be copied implicitly
#[component]
fn MyComponent(string: String) -> Element {
rsx! {
button {
// ❌ We are moving the string into the onclick handler which means we can't access it elsewhere
onclick: move |_| {
println!("{string}");
},
"Print hello world"
}
button {
// ❌ Since we already moved the string, we can't move it into the onclick handler again. This will cause a compiler error
onclick: move |_| {
println!("{string}");
},
"Print hello world again"
}
}
}You can fix this issue by either:
- Making your data
CopywithReadSignal:
// `MyComponent` accepts `ReadSignal<String>` which implements `Copy`
#[component]
fn MyComponent(string: ReadSignal<String>) -> Element {
rsx! {
button {
// ✅ Because the `string` signal is `Copy`, we can copy it into the closure while still having access to it elsewhere
onclick: move |_| println!("{}", string),
"Print hello world"
}
button {
// ✅ Since `string` is `Copy`, we can move it into the onclick handler again
onclick: move |_| println!("{}", string),
"Print hello world again"
}
}
}- Calling
cloneon your data before you move it into the closure:
// `MyComponent` accepts a string which doesn't implement `Copy`
#[component]
fn MyComponent(string: String) -> Element {
rsx! {
button {
// ✅ The string only has one owner. We could move it into this closure, but since we want to use the string in other closures later, we will clone it instead
onclick: {
// Clone the string in a new block
let string = string.clone();
// Then move the cloned string into the closure
move |_| println!("{}", string)
},
"Print hello world"
}
button {
// ✅ We don't use the string after this closure, so we can just move it into the closure directly
onclick: move |_| println!("{}", string),
"Print hello world again"
}
}
}Sourcefn ontouchmove<__Marker>(
self,
event_handler: impl EventHandlerValue<TouchData, __Marker>,
) -> <Self as AttributeBuilderTarget>::Output
fn ontouchmove<__Marker>( self, event_handler: impl EventHandlerValue<TouchData, __Marker>, ) -> <Self as AttributeBuilderTarget>::Output
ontouchmove
General Event Handler Information
§Event Handlers
Event Handlers let you react to user input in your application. In Dioxus, event handlers accept a closure that is called when the event occurs:
use dioxus::prelude::*;
fn App() -> Element {
rsx! {
button {
// The `onclick` event accepts a closure with the signature `fn(Event)`
onclick: |event_data| println!("clicked! I got the event data: {event_data:?}"),
"Click me"
}
}
}§Event Lifetimes
Events take a closure with the 'static lifetime. This means that the closure can only access data that either exists for the entire lifetime of the application, or data that you move into the closure.
State in dioxus is copy which makes it very easy to move into 'static closures like event handlers:
let mut count = use_signal(|| 0);
rsx! {
button {
// Since we added the `move` keyword, the closure will move the `count` signal into the closure
onclick: move |_| {
// This will panic because the `count` signal is not in scope
count.set(count() + 1);
},
"Click me"
}
};If you need to access data that is not Copy, you may need to clone the data before you move it into the closure:
// String is not `Copy`
let string = "hello world".to_string();
rsx! {
button {
// The string only has one owner. We could move it into this closure, but since we want to use the string in other closures later, we will clone it instead
onclick: {
// Clone the string in a new block
let string = string.clone();
// Then move the cloned string into the closure
move |_| println!("{}", string)
},
"Print hello world"
}
button {
// We don't use the string after this closure, so we can just move it into the closure directly
onclick: move |_| println!("{}", string),
"Print hello world again"
}
};§Async Event Handlers
In addition to closures that return nothing, you can also use async closures to handle events. If you return an async block from an event handler, dioxus will automatically spawn it:
use dioxus::prelude::*;
fn App() -> Element {
rsx! {
button {
// The `onclick` event can also accept a closure that returns an async block
onclick: move |_| async move {
tokio::time::sleep(std::time::Duration::from_secs(1)).await;
println!("You clicked the button one second ago!");
},
"Click me"
}
}
}§Compiler errors you may run into while using event handlers
function requires argument type to outlive `'static`
Event handler in Dioxus need only access data that can last for the entire lifetime of the application. That generally means data that is moved into the closure. If you get this error, you may have forgotten to add move to your closure.
Broken component:
// We return an Element which can last as long as the component is on the screen
fn App() -> Element {
// Signals are `Copy` which makes them very easy to move into `'static` closures like event handlers
let state = use_signal(|| "hello world".to_string());
rsx! {
button {
// ❌ Without `move`, rust will try to borrow the `state` signal which fails because the state signal is dropped at the end of the function
onclick: |_| {
println!("You clicked the button! The state is: {state}");
},
"Click me"
}
}
// The state signal is dropped here, but the event handler still needs to access it
}Fixed component:
fn App() -> Element {
let state = use_signal(|| "hello world".to_string());
rsx! {
button {
// ✅ The `move` keyword tells rust it can move the `state` signal into the closure. Since the closure owns the signal state, it can read it even after the function returns
onclick: move |_| {
println!("You clicked the button! The state is: {state}");
},
"Click me"
}
}
}use of moved value: `your_value` value used here after move
Data in rust has a single owner. If you run into this error, you have likely tried to move data that isn’t Copy into two different closures. You can fix this issue by making your data Copy or calling clone on it before you move it into the closure.
Broken component:
// `MyComponent` accepts a string which cannot be copied implicitly
#[component]
fn MyComponent(string: String) -> Element {
rsx! {
button {
// ❌ We are moving the string into the onclick handler which means we can't access it elsewhere
onclick: move |_| {
println!("{string}");
},
"Print hello world"
}
button {
// ❌ Since we already moved the string, we can't move it into the onclick handler again. This will cause a compiler error
onclick: move |_| {
println!("{string}");
},
"Print hello world again"
}
}
}You can fix this issue by either:
- Making your data
CopywithReadSignal:
// `MyComponent` accepts `ReadSignal<String>` which implements `Copy`
#[component]
fn MyComponent(string: ReadSignal<String>) -> Element {
rsx! {
button {
// ✅ Because the `string` signal is `Copy`, we can copy it into the closure while still having access to it elsewhere
onclick: move |_| println!("{}", string),
"Print hello world"
}
button {
// ✅ Since `string` is `Copy`, we can move it into the onclick handler again
onclick: move |_| println!("{}", string),
"Print hello world again"
}
}
}- Calling
cloneon your data before you move it into the closure:
// `MyComponent` accepts a string which doesn't implement `Copy`
#[component]
fn MyComponent(string: String) -> Element {
rsx! {
button {
// ✅ The string only has one owner. We could move it into this closure, but since we want to use the string in other closures later, we will clone it instead
onclick: {
// Clone the string in a new block
let string = string.clone();
// Then move the cloned string into the closure
move |_| println!("{}", string)
},
"Print hello world"
}
button {
// ✅ We don't use the string after this closure, so we can just move it into the closure directly
onclick: move |_| println!("{}", string),
"Print hello world again"
}
}
}Sourcefn ontouchend<__Marker>(
self,
event_handler: impl EventHandlerValue<TouchData, __Marker>,
) -> <Self as AttributeBuilderTarget>::Output
fn ontouchend<__Marker>( self, event_handler: impl EventHandlerValue<TouchData, __Marker>, ) -> <Self as AttributeBuilderTarget>::Output
ontouchend
General Event Handler Information
§Event Handlers
Event Handlers let you react to user input in your application. In Dioxus, event handlers accept a closure that is called when the event occurs:
use dioxus::prelude::*;
fn App() -> Element {
rsx! {
button {
// The `onclick` event accepts a closure with the signature `fn(Event)`
onclick: |event_data| println!("clicked! I got the event data: {event_data:?}"),
"Click me"
}
}
}§Event Lifetimes
Events take a closure with the 'static lifetime. This means that the closure can only access data that either exists for the entire lifetime of the application, or data that you move into the closure.
State in dioxus is copy which makes it very easy to move into 'static closures like event handlers:
let mut count = use_signal(|| 0);
rsx! {
button {
// Since we added the `move` keyword, the closure will move the `count` signal into the closure
onclick: move |_| {
// This will panic because the `count` signal is not in scope
count.set(count() + 1);
},
"Click me"
}
};If you need to access data that is not Copy, you may need to clone the data before you move it into the closure:
// String is not `Copy`
let string = "hello world".to_string();
rsx! {
button {
// The string only has one owner. We could move it into this closure, but since we want to use the string in other closures later, we will clone it instead
onclick: {
// Clone the string in a new block
let string = string.clone();
// Then move the cloned string into the closure
move |_| println!("{}", string)
},
"Print hello world"
}
button {
// We don't use the string after this closure, so we can just move it into the closure directly
onclick: move |_| println!("{}", string),
"Print hello world again"
}
};§Async Event Handlers
In addition to closures that return nothing, you can also use async closures to handle events. If you return an async block from an event handler, dioxus will automatically spawn it:
use dioxus::prelude::*;
fn App() -> Element {
rsx! {
button {
// The `onclick` event can also accept a closure that returns an async block
onclick: move |_| async move {
tokio::time::sleep(std::time::Duration::from_secs(1)).await;
println!("You clicked the button one second ago!");
},
"Click me"
}
}
}§Compiler errors you may run into while using event handlers
function requires argument type to outlive `'static`
Event handler in Dioxus need only access data that can last for the entire lifetime of the application. That generally means data that is moved into the closure. If you get this error, you may have forgotten to add move to your closure.
Broken component:
// We return an Element which can last as long as the component is on the screen
fn App() -> Element {
// Signals are `Copy` which makes them very easy to move into `'static` closures like event handlers
let state = use_signal(|| "hello world".to_string());
rsx! {
button {
// ❌ Without `move`, rust will try to borrow the `state` signal which fails because the state signal is dropped at the end of the function
onclick: |_| {
println!("You clicked the button! The state is: {state}");
},
"Click me"
}
}
// The state signal is dropped here, but the event handler still needs to access it
}Fixed component:
fn App() -> Element {
let state = use_signal(|| "hello world".to_string());
rsx! {
button {
// ✅ The `move` keyword tells rust it can move the `state` signal into the closure. Since the closure owns the signal state, it can read it even after the function returns
onclick: move |_| {
println!("You clicked the button! The state is: {state}");
},
"Click me"
}
}
}use of moved value: `your_value` value used here after move
Data in rust has a single owner. If you run into this error, you have likely tried to move data that isn’t Copy into two different closures. You can fix this issue by making your data Copy or calling clone on it before you move it into the closure.
Broken component:
// `MyComponent` accepts a string which cannot be copied implicitly
#[component]
fn MyComponent(string: String) -> Element {
rsx! {
button {
// ❌ We are moving the string into the onclick handler which means we can't access it elsewhere
onclick: move |_| {
println!("{string}");
},
"Print hello world"
}
button {
// ❌ Since we already moved the string, we can't move it into the onclick handler again. This will cause a compiler error
onclick: move |_| {
println!("{string}");
},
"Print hello world again"
}
}
}You can fix this issue by either:
- Making your data
CopywithReadSignal:
// `MyComponent` accepts `ReadSignal<String>` which implements `Copy`
#[component]
fn MyComponent(string: ReadSignal<String>) -> Element {
rsx! {
button {
// ✅ Because the `string` signal is `Copy`, we can copy it into the closure while still having access to it elsewhere
onclick: move |_| println!("{}", string),
"Print hello world"
}
button {
// ✅ Since `string` is `Copy`, we can move it into the onclick handler again
onclick: move |_| println!("{}", string),
"Print hello world again"
}
}
}- Calling
cloneon your data before you move it into the closure:
// `MyComponent` accepts a string which doesn't implement `Copy`
#[component]
fn MyComponent(string: String) -> Element {
rsx! {
button {
// ✅ The string only has one owner. We could move it into this closure, but since we want to use the string in other closures later, we will clone it instead
onclick: {
// Clone the string in a new block
let string = string.clone();
// Then move the cloned string into the closure
move |_| println!("{}", string)
},
"Print hello world"
}
button {
// ✅ We don't use the string after this closure, so we can just move it into the closure directly
onclick: move |_| println!("{}", string),
"Print hello world again"
}
}
}Sourcefn ontouchcancel<__Marker>(
self,
event_handler: impl EventHandlerValue<TouchData, __Marker>,
) -> <Self as AttributeBuilderTarget>::Output
fn ontouchcancel<__Marker>( self, event_handler: impl EventHandlerValue<TouchData, __Marker>, ) -> <Self as AttributeBuilderTarget>::Output
ontouchcancel
General Event Handler Information
§Event Handlers
Event Handlers let you react to user input in your application. In Dioxus, event handlers accept a closure that is called when the event occurs:
use dioxus::prelude::*;
fn App() -> Element {
rsx! {
button {
// The `onclick` event accepts a closure with the signature `fn(Event)`
onclick: |event_data| println!("clicked! I got the event data: {event_data:?}"),
"Click me"
}
}
}§Event Lifetimes
Events take a closure with the 'static lifetime. This means that the closure can only access data that either exists for the entire lifetime of the application, or data that you move into the closure.
State in dioxus is copy which makes it very easy to move into 'static closures like event handlers:
let mut count = use_signal(|| 0);
rsx! {
button {
// Since we added the `move` keyword, the closure will move the `count` signal into the closure
onclick: move |_| {
// This will panic because the `count` signal is not in scope
count.set(count() + 1);
},
"Click me"
}
};If you need to access data that is not Copy, you may need to clone the data before you move it into the closure:
// String is not `Copy`
let string = "hello world".to_string();
rsx! {
button {
// The string only has one owner. We could move it into this closure, but since we want to use the string in other closures later, we will clone it instead
onclick: {
// Clone the string in a new block
let string = string.clone();
// Then move the cloned string into the closure
move |_| println!("{}", string)
},
"Print hello world"
}
button {
// We don't use the string after this closure, so we can just move it into the closure directly
onclick: move |_| println!("{}", string),
"Print hello world again"
}
};§Async Event Handlers
In addition to closures that return nothing, you can also use async closures to handle events. If you return an async block from an event handler, dioxus will automatically spawn it:
use dioxus::prelude::*;
fn App() -> Element {
rsx! {
button {
// The `onclick` event can also accept a closure that returns an async block
onclick: move |_| async move {
tokio::time::sleep(std::time::Duration::from_secs(1)).await;
println!("You clicked the button one second ago!");
},
"Click me"
}
}
}§Compiler errors you may run into while using event handlers
function requires argument type to outlive `'static`
Event handler in Dioxus need only access data that can last for the entire lifetime of the application. That generally means data that is moved into the closure. If you get this error, you may have forgotten to add move to your closure.
Broken component:
// We return an Element which can last as long as the component is on the screen
fn App() -> Element {
// Signals are `Copy` which makes them very easy to move into `'static` closures like event handlers
let state = use_signal(|| "hello world".to_string());
rsx! {
button {
// ❌ Without `move`, rust will try to borrow the `state` signal which fails because the state signal is dropped at the end of the function
onclick: |_| {
println!("You clicked the button! The state is: {state}");
},
"Click me"
}
}
// The state signal is dropped here, but the event handler still needs to access it
}Fixed component:
fn App() -> Element {
let state = use_signal(|| "hello world".to_string());
rsx! {
button {
// ✅ The `move` keyword tells rust it can move the `state` signal into the closure. Since the closure owns the signal state, it can read it even after the function returns
onclick: move |_| {
println!("You clicked the button! The state is: {state}");
},
"Click me"
}
}
}use of moved value: `your_value` value used here after move
Data in rust has a single owner. If you run into this error, you have likely tried to move data that isn’t Copy into two different closures. You can fix this issue by making your data Copy or calling clone on it before you move it into the closure.
Broken component:
// `MyComponent` accepts a string which cannot be copied implicitly
#[component]
fn MyComponent(string: String) -> Element {
rsx! {
button {
// ❌ We are moving the string into the onclick handler which means we can't access it elsewhere
onclick: move |_| {
println!("{string}");
},
"Print hello world"
}
button {
// ❌ Since we already moved the string, we can't move it into the onclick handler again. This will cause a compiler error
onclick: move |_| {
println!("{string}");
},
"Print hello world again"
}
}
}You can fix this issue by either:
- Making your data
CopywithReadSignal:
// `MyComponent` accepts `ReadSignal<String>` which implements `Copy`
#[component]
fn MyComponent(string: ReadSignal<String>) -> Element {
rsx! {
button {
// ✅ Because the `string` signal is `Copy`, we can copy it into the closure while still having access to it elsewhere
onclick: move |_| println!("{}", string),
"Print hello world"
}
button {
// ✅ Since `string` is `Copy`, we can move it into the onclick handler again
onclick: move |_| println!("{}", string),
"Print hello world again"
}
}
}- Calling
cloneon your data before you move it into the closure:
// `MyComponent` accepts a string which doesn't implement `Copy`
#[component]
fn MyComponent(string: String) -> Element {
rsx! {
button {
// ✅ The string only has one owner. We could move it into this closure, but since we want to use the string in other closures later, we will clone it instead
onclick: {
// Clone the string in a new block
let string = string.clone();
// Then move the cloned string into the closure
move |_| println!("{}", string)
},
"Print hello world"
}
button {
// ✅ We don't use the string after this closure, so we can just move it into the closure directly
onclick: move |_| println!("{}", string),
"Print hello world again"
}
}
}Sourcefn ontransitionend<__Marker>(
self,
event_handler: impl EventHandlerValue<TransitionData, __Marker>,
) -> <Self as AttributeBuilderTarget>::Output
fn ontransitionend<__Marker>( self, event_handler: impl EventHandlerValue<TransitionData, __Marker>, ) -> <Self as AttributeBuilderTarget>::Output
ontransitionend
General Event Handler Information
§Event Handlers
Event Handlers let you react to user input in your application. In Dioxus, event handlers accept a closure that is called when the event occurs:
use dioxus::prelude::*;
fn App() -> Element {
rsx! {
button {
// The `onclick` event accepts a closure with the signature `fn(Event)`
onclick: |event_data| println!("clicked! I got the event data: {event_data:?}"),
"Click me"
}
}
}§Event Lifetimes
Events take a closure with the 'static lifetime. This means that the closure can only access data that either exists for the entire lifetime of the application, or data that you move into the closure.
State in dioxus is copy which makes it very easy to move into 'static closures like event handlers:
let mut count = use_signal(|| 0);
rsx! {
button {
// Since we added the `move` keyword, the closure will move the `count` signal into the closure
onclick: move |_| {
// This will panic because the `count` signal is not in scope
count.set(count() + 1);
},
"Click me"
}
};If you need to access data that is not Copy, you may need to clone the data before you move it into the closure:
// String is not `Copy`
let string = "hello world".to_string();
rsx! {
button {
// The string only has one owner. We could move it into this closure, but since we want to use the string in other closures later, we will clone it instead
onclick: {
// Clone the string in a new block
let string = string.clone();
// Then move the cloned string into the closure
move |_| println!("{}", string)
},
"Print hello world"
}
button {
// We don't use the string after this closure, so we can just move it into the closure directly
onclick: move |_| println!("{}", string),
"Print hello world again"
}
};§Async Event Handlers
In addition to closures that return nothing, you can also use async closures to handle events. If you return an async block from an event handler, dioxus will automatically spawn it:
use dioxus::prelude::*;
fn App() -> Element {
rsx! {
button {
// The `onclick` event can also accept a closure that returns an async block
onclick: move |_| async move {
tokio::time::sleep(std::time::Duration::from_secs(1)).await;
println!("You clicked the button one second ago!");
},
"Click me"
}
}
}§Compiler errors you may run into while using event handlers
function requires argument type to outlive `'static`
Event handler in Dioxus need only access data that can last for the entire lifetime of the application. That generally means data that is moved into the closure. If you get this error, you may have forgotten to add move to your closure.
Broken component:
// We return an Element which can last as long as the component is on the screen
fn App() -> Element {
// Signals are `Copy` which makes them very easy to move into `'static` closures like event handlers
let state = use_signal(|| "hello world".to_string());
rsx! {
button {
// ❌ Without `move`, rust will try to borrow the `state` signal which fails because the state signal is dropped at the end of the function
onclick: |_| {
println!("You clicked the button! The state is: {state}");
},
"Click me"
}
}
// The state signal is dropped here, but the event handler still needs to access it
}Fixed component:
fn App() -> Element {
let state = use_signal(|| "hello world".to_string());
rsx! {
button {
// ✅ The `move` keyword tells rust it can move the `state` signal into the closure. Since the closure owns the signal state, it can read it even after the function returns
onclick: move |_| {
println!("You clicked the button! The state is: {state}");
},
"Click me"
}
}
}use of moved value: `your_value` value used here after move
Data in rust has a single owner. If you run into this error, you have likely tried to move data that isn’t Copy into two different closures. You can fix this issue by making your data Copy or calling clone on it before you move it into the closure.
Broken component:
// `MyComponent` accepts a string which cannot be copied implicitly
#[component]
fn MyComponent(string: String) -> Element {
rsx! {
button {
// ❌ We are moving the string into the onclick handler which means we can't access it elsewhere
onclick: move |_| {
println!("{string}");
},
"Print hello world"
}
button {
// ❌ Since we already moved the string, we can't move it into the onclick handler again. This will cause a compiler error
onclick: move |_| {
println!("{string}");
},
"Print hello world again"
}
}
}You can fix this issue by either:
- Making your data
CopywithReadSignal:
// `MyComponent` accepts `ReadSignal<String>` which implements `Copy`
#[component]
fn MyComponent(string: ReadSignal<String>) -> Element {
rsx! {
button {
// ✅ Because the `string` signal is `Copy`, we can copy it into the closure while still having access to it elsewhere
onclick: move |_| println!("{}", string),
"Print hello world"
}
button {
// ✅ Since `string` is `Copy`, we can move it into the onclick handler again
onclick: move |_| println!("{}", string),
"Print hello world again"
}
}
}- Calling
cloneon your data before you move it into the closure:
// `MyComponent` accepts a string which doesn't implement `Copy`
#[component]
fn MyComponent(string: String) -> Element {
rsx! {
button {
// ✅ The string only has one owner. We could move it into this closure, but since we want to use the string in other closures later, we will clone it instead
onclick: {
// Clone the string in a new block
let string = string.clone();
// Then move the cloned string into the closure
move |_| println!("{}", string)
},
"Print hello world"
}
button {
// ✅ We don't use the string after this closure, so we can just move it into the closure directly
onclick: move |_| println!("{}", string),
"Print hello world again"
}
}
}Sourcefn onvisible<__Marker>(
self,
event_handler: impl EventHandlerValue<VisibleData, __Marker>,
) -> <Self as AttributeBuilderTarget>::Output
fn onvisible<__Marker>( self, event_handler: impl EventHandlerValue<VisibleData, __Marker>, ) -> <Self as AttributeBuilderTarget>::Output
onvisible
General Event Handler Information
§Event Handlers
Event Handlers let you react to user input in your application. In Dioxus, event handlers accept a closure that is called when the event occurs:
use dioxus::prelude::*;
fn App() -> Element {
rsx! {
button {
// The `onclick` event accepts a closure with the signature `fn(Event)`
onclick: |event_data| println!("clicked! I got the event data: {event_data:?}"),
"Click me"
}
}
}§Event Lifetimes
Events take a closure with the 'static lifetime. This means that the closure can only access data that either exists for the entire lifetime of the application, or data that you move into the closure.
State in dioxus is copy which makes it very easy to move into 'static closures like event handlers:
let mut count = use_signal(|| 0);
rsx! {
button {
// Since we added the `move` keyword, the closure will move the `count` signal into the closure
onclick: move |_| {
// This will panic because the `count` signal is not in scope
count.set(count() + 1);
},
"Click me"
}
};If you need to access data that is not Copy, you may need to clone the data before you move it into the closure:
// String is not `Copy`
let string = "hello world".to_string();
rsx! {
button {
// The string only has one owner. We could move it into this closure, but since we want to use the string in other closures later, we will clone it instead
onclick: {
// Clone the string in a new block
let string = string.clone();
// Then move the cloned string into the closure
move |_| println!("{}", string)
},
"Print hello world"
}
button {
// We don't use the string after this closure, so we can just move it into the closure directly
onclick: move |_| println!("{}", string),
"Print hello world again"
}
};§Async Event Handlers
In addition to closures that return nothing, you can also use async closures to handle events. If you return an async block from an event handler, dioxus will automatically spawn it:
use dioxus::prelude::*;
fn App() -> Element {
rsx! {
button {
// The `onclick` event can also accept a closure that returns an async block
onclick: move |_| async move {
tokio::time::sleep(std::time::Duration::from_secs(1)).await;
println!("You clicked the button one second ago!");
},
"Click me"
}
}
}§Compiler errors you may run into while using event handlers
function requires argument type to outlive `'static`
Event handler in Dioxus need only access data that can last for the entire lifetime of the application. That generally means data that is moved into the closure. If you get this error, you may have forgotten to add move to your closure.
Broken component:
// We return an Element which can last as long as the component is on the screen
fn App() -> Element {
// Signals are `Copy` which makes them very easy to move into `'static` closures like event handlers
let state = use_signal(|| "hello world".to_string());
rsx! {
button {
// ❌ Without `move`, rust will try to borrow the `state` signal which fails because the state signal is dropped at the end of the function
onclick: |_| {
println!("You clicked the button! The state is: {state}");
},
"Click me"
}
}
// The state signal is dropped here, but the event handler still needs to access it
}Fixed component:
fn App() -> Element {
let state = use_signal(|| "hello world".to_string());
rsx! {
button {
// ✅ The `move` keyword tells rust it can move the `state` signal into the closure. Since the closure owns the signal state, it can read it even after the function returns
onclick: move |_| {
println!("You clicked the button! The state is: {state}");
},
"Click me"
}
}
}use of moved value: `your_value` value used here after move
Data in rust has a single owner. If you run into this error, you have likely tried to move data that isn’t Copy into two different closures. You can fix this issue by making your data Copy or calling clone on it before you move it into the closure.
Broken component:
// `MyComponent` accepts a string which cannot be copied implicitly
#[component]
fn MyComponent(string: String) -> Element {
rsx! {
button {
// ❌ We are moving the string into the onclick handler which means we can't access it elsewhere
onclick: move |_| {
println!("{string}");
},
"Print hello world"
}
button {
// ❌ Since we already moved the string, we can't move it into the onclick handler again. This will cause a compiler error
onclick: move |_| {
println!("{string}");
},
"Print hello world again"
}
}
}You can fix this issue by either:
- Making your data
CopywithReadSignal:
// `MyComponent` accepts `ReadSignal<String>` which implements `Copy`
#[component]
fn MyComponent(string: ReadSignal<String>) -> Element {
rsx! {
button {
// ✅ Because the `string` signal is `Copy`, we can copy it into the closure while still having access to it elsewhere
onclick: move |_| println!("{}", string),
"Print hello world"
}
button {
// ✅ Since `string` is `Copy`, we can move it into the onclick handler again
onclick: move |_| println!("{}", string),
"Print hello world again"
}
}
}- Calling
cloneon your data before you move it into the closure:
// `MyComponent` accepts a string which doesn't implement `Copy`
#[component]
fn MyComponent(string: String) -> Element {
rsx! {
button {
// ✅ The string only has one owner. We could move it into this closure, but since we want to use the string in other closures later, we will clone it instead
onclick: {
// Clone the string in a new block
let string = string.clone();
// Then move the cloned string into the closure
move |_| println!("{}", string)
},
"Print hello world"
}
button {
// ✅ We don't use the string after this closure, so we can just move it into the closure directly
onclick: move |_| println!("{}", string),
"Print hello world again"
}
}
}Sourcefn onwheel<__Marker>(
self,
event_handler: impl EventHandlerValue<WheelData, __Marker>,
) -> <Self as AttributeBuilderTarget>::Output
fn onwheel<__Marker>( self, event_handler: impl EventHandlerValue<WheelData, __Marker>, ) -> <Self as AttributeBuilderTarget>::Output
onwheel Called when the mouse wheel is rotated over an element.
General Event Handler Information
§Event Handlers
Event Handlers let you react to user input in your application. In Dioxus, event handlers accept a closure that is called when the event occurs:
use dioxus::prelude::*;
fn App() -> Element {
rsx! {
button {
// The `onclick` event accepts a closure with the signature `fn(Event)`
onclick: |event_data| println!("clicked! I got the event data: {event_data:?}"),
"Click me"
}
}
}§Event Lifetimes
Events take a closure with the 'static lifetime. This means that the closure can only access data that either exists for the entire lifetime of the application, or data that you move into the closure.
State in dioxus is copy which makes it very easy to move into 'static closures like event handlers:
let mut count = use_signal(|| 0);
rsx! {
button {
// Since we added the `move` keyword, the closure will move the `count` signal into the closure
onclick: move |_| {
// This will panic because the `count` signal is not in scope
count.set(count() + 1);
},
"Click me"
}
};If you need to access data that is not Copy, you may need to clone the data before you move it into the closure:
// String is not `Copy`
let string = "hello world".to_string();
rsx! {
button {
// The string only has one owner. We could move it into this closure, but since we want to use the string in other closures later, we will clone it instead
onclick: {
// Clone the string in a new block
let string = string.clone();
// Then move the cloned string into the closure
move |_| println!("{}", string)
},
"Print hello world"
}
button {
// We don't use the string after this closure, so we can just move it into the closure directly
onclick: move |_| println!("{}", string),
"Print hello world again"
}
};§Async Event Handlers
In addition to closures that return nothing, you can also use async closures to handle events. If you return an async block from an event handler, dioxus will automatically spawn it:
use dioxus::prelude::*;
fn App() -> Element {
rsx! {
button {
// The `onclick` event can also accept a closure that returns an async block
onclick: move |_| async move {
tokio::time::sleep(std::time::Duration::from_secs(1)).await;
println!("You clicked the button one second ago!");
},
"Click me"
}
}
}§Compiler errors you may run into while using event handlers
function requires argument type to outlive `'static`
Event handler in Dioxus need only access data that can last for the entire lifetime of the application. That generally means data that is moved into the closure. If you get this error, you may have forgotten to add move to your closure.
Broken component:
// We return an Element which can last as long as the component is on the screen
fn App() -> Element {
// Signals are `Copy` which makes them very easy to move into `'static` closures like event handlers
let state = use_signal(|| "hello world".to_string());
rsx! {
button {
// ❌ Without `move`, rust will try to borrow the `state` signal which fails because the state signal is dropped at the end of the function
onclick: |_| {
println!("You clicked the button! The state is: {state}");
},
"Click me"
}
}
// The state signal is dropped here, but the event handler still needs to access it
}Fixed component:
fn App() -> Element {
let state = use_signal(|| "hello world".to_string());
rsx! {
button {
// ✅ The `move` keyword tells rust it can move the `state` signal into the closure. Since the closure owns the signal state, it can read it even after the function returns
onclick: move |_| {
println!("You clicked the button! The state is: {state}");
},
"Click me"
}
}
}use of moved value: `your_value` value used here after move
Data in rust has a single owner. If you run into this error, you have likely tried to move data that isn’t Copy into two different closures. You can fix this issue by making your data Copy or calling clone on it before you move it into the closure.
Broken component:
// `MyComponent` accepts a string which cannot be copied implicitly
#[component]
fn MyComponent(string: String) -> Element {
rsx! {
button {
// ❌ We are moving the string into the onclick handler which means we can't access it elsewhere
onclick: move |_| {
println!("{string}");
},
"Print hello world"
}
button {
// ❌ Since we already moved the string, we can't move it into the onclick handler again. This will cause a compiler error
onclick: move |_| {
println!("{string}");
},
"Print hello world again"
}
}
}You can fix this issue by either:
- Making your data
CopywithReadSignal:
// `MyComponent` accepts `ReadSignal<String>` which implements `Copy`
#[component]
fn MyComponent(string: ReadSignal<String>) -> Element {
rsx! {
button {
// ✅ Because the `string` signal is `Copy`, we can copy it into the closure while still having access to it elsewhere
onclick: move |_| println!("{}", string),
"Print hello world"
}
button {
// ✅ Since `string` is `Copy`, we can move it into the onclick handler again
onclick: move |_| println!("{}", string),
"Print hello world again"
}
}
}- Calling
cloneon your data before you move it into the closure:
// `MyComponent` accepts a string which doesn't implement `Copy`
#[component]
fn MyComponent(string: String) -> Element {
rsx! {
button {
// ✅ The string only has one owner. We could move it into this closure, but since we want to use the string in other closures later, we will clone it instead
onclick: {
// Clone the string in a new block
let string = string.clone();
// Then move the cloned string into the closure
move |_| println!("{}", string)
},
"Print hello world"
}
button {
// ✅ We don't use the string after this closure, so we can just move it into the closure directly
onclick: move |_| println!("{}", string),
"Print hello world again"
}
}
}Dyn Compatibility§
This trait is not dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety".