#component #react #key-store #reset #use-state

nightly comp_state

组件状态 - React Hooks use_state的克隆

20个版本

0.2.8 2020年4月8日
0.2.7 2020年3月4日
0.2.2 2020年2月23日
0.1.1 2020年2月17日
0.0.4 2019年11月27日

10 in #reset

Download history • Rust 包仓库 5/week @ 2024-03-08 • Rust 包仓库 2/week @ 2024-03-15 • Rust 包仓库 19/week @ 2024-03-29 • Rust 包仓库 8/week @ 2024-04-05 • Rust 包仓库

87 每月下载
用于 2 crates

MIT/Apache

30KB
631 代码行(不含注释)

comp_state: 在组件上存储状态

comp_state是一个允许您按组件级别存储状态的crate。它设计为React Hooks(主要是useState钩子)的克隆。

在此,组件被定义为“拓扑感知执行上下文”,这意味着组件知道自己在调用树中的调用位置和身份。

comp_state通常在宿主框架的上下文中使用,例如编译为Wasm的Web前端。

示例

这是一个在Seed框架中实现的完整计数按钮状态的示例

use comp_state::{topo, use_state};

#[topo::nested]
fn my_button() -> Node<Msg> {
    let count = use_state(|| 3);

    div![
        count,
        button![count.mouse_ev(Ev::Click, |count, _| *count += 1), "Click me"],
    ]
}

与ReactJs相比

import React, { useState } from 'react';
function Example() {
  // Declare a new state variable, which we'll call "count"
  const [count, setCount] = useState(0);

  return (
    <div>
      <p>You clicked {count} times</p>
      <button onClick={() => setCount(count + 1)}>
        Click me
      </button>
    </div>
  );
}

最重要的两个函数是

  • use_state(|| .. ) 存储闭包返回类型的组件状态。返回状态访问器。
  • #[topo::nested] 函数注释定义了拓扑感知函数。函数内部执行的所有操作都将具有其唯一的拓扑ID。最外层的嵌套函数充当“根”,重置拓扑并允许特定组件具有“拓扑身份”。

注意事项

这是一个纯粹的alpha实验!

每个组件都有自己的“topo::Id”,然后将其用作存储组件状态的键。topo是Moxie团队的一个crate,他们正在为Rust创建一个GUI框架。关于Moxie和topo如何工作的一个有趣的谈话在这里:这里

它是如何工作的?

  • 这依赖于激活 #![feature(track_caller)] 功能门。

  • topo为每个 #[topo::nested] 函数或每个 topo::call 块创建一个新的执行上下文。最外层的调用重新设置执行上下文。重新设置允许在基视图函数开始时重新设置根,这意味着可以为通过 #[topo::nested] 注释的特定组件存储和检索本地数据。

  • 执行上下文不仅由调用顺序决定
    不仅提供了这些调用的功能,还提供了它们的源位置。这意味着即使分支逻辑可能以不同的顺序调用拓扑感知功能,状态也是一致和稳定的。

  • 查看这个解释 topo 的工作原理的精彩演讲:https://www.youtube.com/watch?v=tmM756XZt20

  • 一个类型存储如下:let string = use_state::<String>(||text),它将 text 存储为 String 类型的组件。这返回一个负责获取和设置状态的访问器结构体。

  • 访问器很有用,因为它可以被传递给回调或克隆,或者从不同的拓扑上下文中调用。即 string_acces.set(new_text) 无论在哪里调用都会工作。

  • 目前 comp_state 通过 get() 向存储值暴露克隆,并通过 get_with() 向非 Clone 类型暴露。

  • 经过一些测试,现在这似乎相当稳定。这是实验性的,请不要将其用于任何重要的事情。

为什么会有人想这样做呢?

  • 我想看看 React Hooks 的所有炒作,以及是否可以在 Rust 中实现。

依赖项

~2MB
~43K SLoC