dioxus
dioxus copied to clipboard
can't clear textarea
Problem
using the value attribute for an input allows for clearing the content of the input from within a callback. textarea should be able to do this too.
Steps To Reproduce
Steps to reproduce the behavior:
fn App(cx: Scope) -> Element {
let text = use_state(&cx, String::new);
cx.render(rsx! {
textarea {
value: "{text}",
oninput: move |evt| text.set(evt.value.clone()),
onkeypress: move |evt| {
if evt.key_code == KeyCode::Enter {
text.set(String::from(""));
}
},
},
})
}
- input some text
- press enter
- the text does not disappear
Expected behavior
- the textarea should be cleared
Questionnaire
- [ x ] I'm interested in fixing this myself but don't know where to start
- [ ] I would like to fix and I have a solution
- [ ] I don't have time to fix this right now, but maybe later
Oh, weird, it's the order of the two events firing. It seems like oninput gets called after onkeypress, so the value is being overwriting with the new value. I tried playing with the order of the handlers and it doesn't seem to do anything, so maybe it's how the DOM is handling the events.
I think technically you'd need to prevent default on the event... but you'd need to do it conditionally which we unfortunately don't support 100% right now (coming next version).
In the short term you can work around it.
The even weirder thing here is that the events aren't batched - IE the component is rendering twice as it handles each handler, which shouldn't be happening, so I consider this a bug with event ordering.
fn app(cx: Scope) -> Element {
let model = use_state(&cx, || String::from("asd"));
let clearing_state = &*cx.use_hook(|| Cell::new(false));
cx.render(rsx! {
textarea {
class: "border",
rows: "10",
cols: "80",
value: "{model}",
oninput: move |e| {
if !clearing_state.get() {
clearing_state.set(false);
model.set(e.value.clone())
}
},
onkeydown: move |evt| {
if evt.key_code == KeyCode::Enter {
clearing_state.set(true);
model.set(String::from(""));
}
},
}
})
}
@jkelleyrtp this is very helpful! thank you!
@jkelleyrtp The problem is no longer here. Full code that is working with v0.5
#![allow(non_snake_case)]
use dioxus::prelude::*;
use log::LevelFilter;
fn main() {
// Init debug
dioxus_logger::init(LevelFilter::Info).expect("failed to init logger");
console_error_panic_hook::set_once();
launch(App);
}
fn App() -> Element {
let mut text = use_signal(String::new);
rsx! {
textarea {
value: "{text}",
oninput: move |evt| text.set(evt.value().clone()),
onkeypress: move |evt| {
if evt.key() == Key::Enter {
text.set(String::from(""));
}
},
},
}
}