v0.4.0
DioxusLabs/dioxusv0.4.0Aug 2, 2023by ealmloff
AI Summary
A major version release introducing Fullstack support, a rewritten type-safe router, Suspense, CLI improvements, and cross-platform system API wrappers.
Key Highlights
- Rewritten Type-safe Router with nesting and layout support.
- Fullstack crate for server-side rendering and hydration.
- Suspense feature for waiting on futures.
- CLI improvements including `dx check` and `dx bundle`.
- Dioxus STD for cross-platform system API wrappers.
Breaking Changes
- UseState is not `Copy` (but supports Clone); `for_async` removed.
- UseFuture and UseEffect now take dependency tuples.
- UseCoroutine is now exposed via the context API and takes a receiver.
- Async tasks are canceled when components are dropped.
- The ContextAPI no longer uses RC to share state.
New Features
- Fullstack rendering and communication with `#[server]` functions
- Type-safe Router using derive macros
- Suspense for async data fetching
- CLI tools: check, bundle, and serve with hot reload
- Async Eval for running JS code
- File upload support for dioxus-html
- New onmounted event for DOM access
- Dioxus MDbook and Search crates for documentation
Full Release Notes
# Dioxus 0.4 Github
The Dioxus 0.4 release includes 6 new crates, a ton of new features and a plethora of bug fixes!
Highlights:
- Rewritten Type safe Router
- Fullstack cross-platform meta framework
- Suspense
- CLI Linting
- CLI Bundling
- Rewritten Documentation
- Cross platform system API wrappers: Dioxus STD
# Router
The router has been revamped for the 0.4 release. The router now uses an enum to define routes. If you use this enum to link to a page, the compiler will insure you never link to a page that doesn’t exist. The new router also includes Nesting, Layout, and sitemap support:
```rust
use dioxus::prelude::*;
use dioxus_router::prelude::*;
#[derive(Routable, Clone)]
enum Route {
#[route("/")]
Home {},
#[route("/blog")]
Blog {},
}
fn App(cx: Scope) -> Element {
render! {
Router::<Route> {}
}
}
#[inline_props]
fn Home(cx: Scope) -> Element {
render! {
Link {
to: Route::Blog {},
"Go to the blog"
}
h1 { "Welcome to the Dioxus Blog!" }
}
}
#[inline_props]
fn Blog(cx: Scope) -> Element {
render! {
Link {
to: Route::Home {},
"Go to the home page"
}
h1 { "Blog" }
}
}
```
Huge shoutout to @TeFiLeDo for creating many different prototypes and tests for the new router!
# Fullstack
The 0.4 release introduces the Fullstack crate. The fullstack crate contains adapters for communicating with your
### Fullstack Rendering
The fullstack crate makes it dead simple to create a server side rendered hydrated app with fullstack typesafety. The fullstack crate lets you render your page on the server on every request (or incrementally) and then hydrate it on the client.
```rust
use dioxus::prelude::*;
use dioxus_fullstack::prelude::*;
fn main() {
LaunchBuilder::new(app).launch();
}
fn app(cx: Scope) -> Element {
let mut count = use_state(cx, || 0);
render! {
h1 { "High-Five counter: {count}" }
button { onclick: move |_| count += 1, "Up high!" }
button { onclick: move |_| count -= 1, "Down low!" }
}
}
```
### Fullstack communication
In addition to fullstack rendering, the new fullstack create allows you to communicate with your server effortlessly. You can annotate a function with `#[server]` to make the code inside the function only run on the server. This makes it easy to build a backend for your web or desktop application!
```rust
use dioxus::prelude::*;
use dioxus_fullstack::prelude::*;
fn main() {
LaunchBuilder::new(app).launch();
}
fn app(cx: Scope) -> Element {
let mut count = use_state(cx, || 0);
render! {
h1 { "High-Five counter: {count}" }
button { onclick: move |_| count += 1, "Up high!" }
button { onclick: move |_| count -= 1, "Down low!" }
button {
onclick: move |_| {
to_owned![count];
async move {
let double = double(*count).await.unwrap();
count.set(double);
}
}
}
}
}
#[server]
async fn double(number: usize) -> Result<usize, ServerFnError> {
// This will *only* run on the server
Ok(number * 2)
}
```
# Suspense
0.4 adds the long awaited suspense feature. This allows you to wait for a future on the server and then send the result to the client. You can combine suspense with server functions to wait for some code on your server to finish running before rendering a component:
```rust
use dioxus::prelude::*;
use dioxus_fullstack::prelude::*;
fn main() {
LaunchBuilder::new(app).launch();
}
fn app(cx: Scope) -> Element {
let mut server_data = use_server_future(cx, || get_server_data())?;
render! {
div {
"{server_data:?}"
}
}
}
#[server]
async fn get_server_data() -> Result<usize, ServerFnError> {
Ok(42)
}
```
# CLI Improvements
> The Dioxus CLI has moved into the dioxus main repo
>
The Dioxus CLI is now called `dx` instead of `dioxus`. The 0.4 release of the Dioxus CLI added three main features:
### Dioxus Check
@eventualbuddha has done a fantastic job creating a new Dioxus check command to lint your Dioxus code for errors! It will warn you if your code violates the [rules of hooks](https://dioxuslabs.com/docs/0.3/guide/en/interactivity/hooks.html#rules-of-hooks)
```
dx check
```
<img width="633" alt="Screenshot 2023-07-26 at 1 43 11 PM" src="https://github.com/DioxusLabs/dioxus/assets/66571940/4b665794-a301-4269-86e4-666aa5325764">
### Dioxus Bundle
The Dioxus CLI can now create installers for MacOs and Windows powered by [tauri-bundle](https://lib.rs/crates/tauri-bundler)!
```
dioxus bundle
```
<img width="383" alt="Screenshot 2023-07-26 at 1 50 31 PM" src="https://github.com/DioxusLabs/dioxus/assets/66571940/1b09483b-c46d-48b9-baf1-c0d46779d6a1">
### Desktop Hot Reload
In Dioxus 0.4, rsx hot reloading has moved from the hot reload macro to the CLI for desktop, liveview, fullstack, and TUI applications. Now every platform can use the CLI to start hot reloading:
```
dioxus serve --platform desktop --hot-reload
```
# Mobile
Dioxus now has improved mobile support with a getting started guide and a mobile example!
# Documentation
The documentation has been revamped for the 0.4 release. We now have a short getting started guide that teaches you how to build a hackernews clone in Dioxus.
The new documentation site takes full advantage of the fullstack crate to prerender the pages.
While working on the new docsite we also created two new crates:
- [Dioxus Mdbook](https://github.com/DioxusLabs/include_mdbook) makes it easy to use markdown into your Dioxus components and use Dioxus components in your markdown
- [Dioxus Search](https://github.com/DioxusLabs/dioxus-search) makes it easy to create instant search indexes for your Dioxus page's. It integrates with the Dioxus router's new site map feature to automatically detect searchable pages
Together these crates allow us to make our documentation fully interactive and instantly searchable. The new documentation site contains live code snippets of different components as you walk through the guide.
# Dioxus STD
One of the biggest problems with cross platform development in rust today is finding ergonomic ways to interact with system APIs. @doge and @marc have created a new Dioxus std create that makes it easy to interact with a variety of system APIs in Dioxus across all platforms. It contains helpers for Geolocation, clipboard access, notifications, color schemes, translation, and more!
# Async Eval
@doge has made the use_eval hook significantly more powerful for the 0.4 release of Dioxus. You can now send messages to and from Javascript asynchronously. This feature makes it possible to listen for Javascript events that Dioxus doesn’t officially support (for example the intersection observer API).
# Dioxus HTML
The 0.4 release introduces file upload support for the dioxus-html crate. This makes it easy to upload files to you desktop, liveview, or web application.
This release also introduces a new onmounted event that provides access to some common node APIs like focusing an element or getting the size of an element in a cross platform way.
# Rink and Blitz-core
Dioxus' TUI renderer Rink and WGPU renderer Blitz can now be used without Dioxus. This makes it possible to render your own html into either of these renderers or use these renderers in your own framework. To get started, see the [Blitz](https://github.com/DioxusLabs/blitz/tree/master/blitz-core/examples) and [Rink](https://github.com/DioxusLabs/dioxus/tree/master/packages/rink/examples) framework-less examples.
# Community
## Office Hours
Dioxus now holds weekly office hours in the discord! If you are interested in the project, need help with your projects, or want to get started contributing, you should come to our weekly office hours!
The office hours happen every Friday at 9:00 AM (PDT) in the [Dioxus discord server](https://discord.gg/XgGxMSkvUM)
Recordings of office hours are available on the [Dioxus youtube channel](https://www.youtube.com/@DioxusLabs)
## New contributors
There have been almost 50 new contributors since the 0.3 release!
@mirkootter, @davidpdrsn, @mwcz, @askreet, @marcerhans, @ndarilek, @arniu, @pickfire, @arqalite, @ProfXwing, @Icekey, @willothy, @rtwfroody, @attilio, @stephenandary, @Rigellute, @onweru, @Byron, @nicoburns, @serzhiio, @indiv0, @azriel91, @elliotwaite, @nmlt, @nicholastmosher, @TimothyStiles, @jpearnshaw, @jmsfltchr, @striezel, @echochamber, @xinglixing, @sean, @torsteingrindvik, @vanhouc, @terhechte, @traxys, @Mouradost, @DianQK, @eventualbuddha, @leahiel, @kaid, @frisoft, @Niedzwiedzw
# Conclusion
For more information on the 0.4 release and all the new features that have been introduced, [read the blogpost](https://dioxuslabs.com/blog/release-040/)
**Full Changelog**: https://github.com/DioxusLabs/dioxus/compare/v0.3.2...v0.4.0