-
-
Notifications
You must be signed in to change notification settings - Fork 1.5k
Description
Problem
Hooks must be executed in the same order otherwise the function component will panic when trying to convert the hook from hook state for the wrong hook type.
This was mentioned in #1129 and deserves it's own issue.
I have considered this a bug because it's a runtime panic and there are no guards against a user doing this by accident.
Steps To Reproduce
Minimal Code to reproduce panic:
use yew::{functional::*, html};
#[function_component(Counter)]
pub fn counter() -> Html {
let count = use_state(|| 0);
if *count % 2 == 0 {
use_ref(|| 0);
} else {
use_effect(|| || {});
}
let onclick = move |_| {
count.set(*count + 1);
};
html! {
<div>
<button {onclick}>{ "Count" }</button>
</div>
}
}
fn main() {
yew::start_app::<Counter>();
}Load this app up in the browser, it will render once without issue but once you click the "Count" button it will panic:
panicked at 'Incompatible hook type. Hooks must always be called in the same order', Not very useful even if it did work correctly but keeps it as simple as possible to cause the panic.
Expected behavior
To either fail at compile time when trying to use a hook conditionally or for hooks to not depend on the order in which they run to work correctly.
Environment:
- Yew version:
master
As mentioned in #1129 a possible solution is to macro-fy the hook API so that in the macro we can sneak in calls to line!/column!/file!.
Edit: The possible solution above would not solve this issue.