Dioxus futures confusion: Futures not being run

Summary

The issue at hand is related to Dioxus futures confusion, where a future is not being executed as expected, resulting in no data being displayed on the page. The code in question uses use_future to fetch a user’s name from a database, but the future is not being run, and no errors are being reported.

Root Cause

The root cause of this issue is likely due to the fact that use_future is being used incorrectly. The use_future hook in Dioxus is used to create a future that can be used to fetch data, but it requires careful handling to ensure that the future is actually executed. Some possible causes include:

  • The future is not being properly awaited
  • The future is being cancelled before it can complete
  • The future is not being properly handled in the component

Why This Happens in Real Systems

This issue can occur in real systems due to a variety of reasons, including:

  • Insufficient error handling: If errors are not properly handled, they can be swallowed, making it difficult to diagnose issues
  • Incorrect usage of async/await: If async/await is not used correctly, futures may not be properly executed
  • Lack of understanding of Dioxus internals: Without a deep understanding of how Dioxus works, it can be difficult to diagnose and fix issues related to futures

Real-World Impact

The real-world impact of this issue can be significant, including:

  • Data not being displayed: If futures are not being executed, data may not be fetched, resulting in blank or incomplete pages
  • Errors not being reported: If errors are not properly handled, they may not be reported, making it difficult to diagnose and fix issues
  • Performance issues: If futures are not being properly handled, they can cause performance issues, such as slow page loads or crashes

Example or Code

use dioxus::prelude::*;

#[component]
pub fn Meals(cx: Scope) -> Element {
    let mut cook = use_signal(cx, || String::new());
    use_future(cx, async move {
        match get_name(2).await {
            Ok(s) => {
                cook.set(s);
            }
            Err(e) => {
                panic!("Future error: {:?}", e);
            }
        }
    });
    rsx! {
        span {
            "{cook}"
        }
    }
}

#[server]
pub async fn get_name(user_id: i32) -> Result {
    use sqlx::FromRow;
    let user_query_result = DATABASE
        .fetch_one(sqlx::query("SELECT * FROM users WHERE user_id = $1").bind(user_id))
        .await;
    let user_row = match user_query_result {
        Ok(u) => u,
        Err(e) => {
            return Err(e);
        }
    };
    let sql_user_name = match SqlUser::from_row(&user_row) {
        Ok(s) => s,
        Err(e) => {
            return Err(e);
        }
    };
    Ok(sql_user_name.get_name().to_string())
}

How Senior Engineers Fix It

Senior engineers can fix this issue by:

  • Carefully reviewing the code: To ensure that use_future is being used correctly and that errors are being properly handled
  • Using debugging tools: To diagnose issues and understand what is happening with the future
  • Testing the future in isolation: To ensure that the future is working as expected

Why Juniors Miss It

Juniors may miss this issue due to:

  • Lack of experience with async/await: Which can make it difficult to understand how futures work and how to properly handle them
  • Insufficient understanding of Dioxus internals: Which can make it difficult to diagnose and fix issues related to futures
  • Inadequate testing: Which can make it difficult to catch issues related to futures before they cause problems in production