macro_rules! export_components {
    {} => { ... };
    {
    $( #[$meta:meta] )*
    $Component:ident $( , $( $tail:tt )* )?
  } => { ... };
    {
    $( #[$meta:meta] )*
    $Component:ty as $Name:ident $( , $( $tail:tt )* )?
  } => { ... };
}
Expand description

This macro can be used to expose your Component for JS consumption via wasm-bindgen.

Requirement is that your component is 'static and implements the TryFrom<JsValue, Error = JsValue> trait. Keep in mind that you do can’t export anything else that has the same name as your component.

Therefore, it is only recommended to use this macro if you’re writing a library for JS consumption only, or if you’re writing a standalone application, since this will pollute the export namespace, which isn’t desirable if you’re writing a library for Rust consumption only.

Example

Implement TryFrom<JsValue, Error = JsValue> on your component and export it:

pub struct Counter {
  counter: i32,
}

impl Component for Counter {
  /* … */
}

impl TryFrom<JsValue> for Counter {
  type Error = JsValue;

  fn try_from(value: JsValue) -> Result<Self, Self::Error> {
    let diff = Reflect::get(&value, &"counter".into())?
      .as_f64()
      .ok_or(JsError::new("`counter` property not found"))?;

    Ok(Counter { counter: diff as i32 })
  }
}

export_components! { Counter }

In JS, you can use it like any other component:

import React from "react";
import init, { Counter } from "./path/to/pkg/project.js";

function SomeOtherJsComponent(props) {
  return (
    <div>
      <Counter counter={0} />
    </div>
  );
}

You can export multiple components and also rename them:

export_components! {
  /// Some doc comment for the exported component.
  App as CounterApp,
  Counter
}