Skip to content

Commit e58d02d

Browse files
committed
rework: rename get() to value_rc(), fix for new internals, add docs
- Renamed get() to value_rc() on both UseStateHandle and UseReducerHandle to avoid shadowing Deref targets that define their own get() (e.g. Cell, RefCell, Option). - Updated UseReducerHandle::value_rc() and into_inner() to work with the new current_state: Rc<RefCell<Rc<T>>> internals. - Reverted the no-longer-needed disambiguation in suspense/hooks.rs. - Added explicit transmute type annotations to satisfy clippy. - Updated timer_functional example to showcase into_inner(). - Added docs for value_rc() and into_inner() in en, ja, zh-Hans, zh-Hant.
1 parent 0a586f5 commit e58d02d

7 files changed

Lines changed: 154 additions & 21 deletions

File tree

  • examples/timer_functional/src
  • packages/yew/src
  • website
    • docs/concepts/function-components
    • i18n
      • ja/docusaurus-plugin-content-docs/current/concepts/function-components
      • zh-Hans/docusaurus-plugin-content-docs/current/concepts/function-components
      • zh-Hant/docusaurus-plugin-content-docs/current/concepts/function-components

examples/timer_functional/src/main.rs

Lines changed: 13 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -122,8 +122,10 @@ fn App() -> Html {
122122
timeout_handle: None,
123123
});
124124

125+
let (state_value, dispatcher) = state.into_inner();
126+
125127
let mut key = 0;
126-
let messages: Html = state
128+
let messages: Html = state_value
127129
.messages
128130
.iter()
129131
.map(|message| {
@@ -132,39 +134,33 @@ fn App() -> Html {
132134
})
133135
.collect();
134136

135-
let has_job = state.interval_handle.is_some() || state.timeout_handle.is_some();
137+
let has_job = state_value.interval_handle.is_some() || state_value.timeout_handle.is_some();
136138

137139
let on_add_timeout = {
138-
let state = state.clone();
139-
140+
let dispatcher = dispatcher.clone();
140141
Callback::from(move |_: MouseEvent| {
141-
let timeout_state = state.clone();
142-
let message_state = state.clone();
142+
let done_dispatcher = dispatcher.clone();
143143
let t = Timeout::new(3000, move || {
144-
message_state.dispatch(TimerAction::TimeoutDone);
144+
done_dispatcher.dispatch(TimerAction::TimeoutDone);
145145
});
146-
147-
timeout_state.dispatch(TimerAction::SetTimeout(t));
146+
dispatcher.dispatch(TimerAction::SetTimeout(t));
148147
})
149148
};
150149

151150
let on_add_interval = {
152-
let state = state.clone();
153-
151+
let dispatcher = dispatcher.clone();
154152
Callback::from(move |_: MouseEvent| {
155-
let interval_state = state.clone();
156-
let message_state = state.clone();
153+
let tick_dispatcher = dispatcher.clone();
157154
let i = Interval::new(1000, move || {
158-
message_state.dispatch(TimerAction::Add("Tick.."));
155+
tick_dispatcher.dispatch(TimerAction::Add("Tick.."));
159156
});
160-
161-
interval_state.dispatch(TimerAction::SetInterval(i));
157+
dispatcher.dispatch(TimerAction::SetInterval(i));
162158
})
163159
};
164160

165161
let on_cancel = {
166162
Callback::from(move |_: MouseEvent| {
167-
state.dispatch(TimerAction::Cancel);
163+
dispatcher.dispatch(TimerAction::Cancel);
168164
})
169165
};
170166

packages/yew/src/functional/hooks/use_state.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,7 @@ impl<T> UseStateHandle<T> {
124124
pub fn value_rc(&self) -> Rc<T> {
125125
// SAFETY: `UseStateReducer<T>` is `repr(transparent)` over `T`, so
126126
// `Rc<UseStateReducer<T>>` and `Rc<T>` have identical layouts.
127-
unsafe { transmute(self.inner.value_rc()) }
127+
unsafe { transmute::<Rc<UseStateReducer<T>>, Rc<T>>(self.inner.value_rc()) }
128128
}
129129

130130
/// Replaces the value
@@ -144,7 +144,10 @@ impl<T> UseStateHandle<T> {
144144
pub fn into_inner(self) -> (Rc<T>, UseStateSetter<T>) {
145145
let (data, inner) = self.inner.into_inner();
146146
// SAFETY: same repr(transparent) guarantee as `value_rc`.
147-
(unsafe { transmute(data) }, UseStateSetter { inner })
147+
(
148+
unsafe { transmute::<Rc<UseStateReducer<T>>, Rc<T>>(data) },
149+
UseStateSetter { inner },
150+
)
148151
}
149152
}
150153

packages/yew/src/suspense/hooks.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -108,14 +108,14 @@ where
108108

109109
use_memo_base(
110110
move |deps| {
111-
let self_id = (*latest_id).get().wrapping_add(1);
111+
let self_id = latest_id.get().wrapping_add(1);
112112
// As long as less than 2**32 futures are in flight wrapping_add is fine
113113
(*latest_id).set(self_id);
114114
let deps = Rc::new(deps);
115115
let task = f(deps.clone());
116116
let suspension = Suspension::from_future(async move {
117117
let result = task.await;
118-
if (*latest_id).get() == self_id {
118+
if latest_id.get() == self_id {
119119
output.set(Some(result));
120120
}
121121
});

website/docs/concepts/function-components/state.mdx

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,41 @@ This table can be used as a guide when deciding what state-storing type fits bes
1717
| [use_mut_ref] | `T` | - | component instance |
1818
| a static global variable | `T` | - | global, used by all |
1919

20+
## Accessing handle internals
21+
22+
Both `UseStateHandle` and `UseReducerHandle` provide methods to access their internal parts directly.
23+
24+
### `value_rc()`
25+
26+
Returns the current value wrapped in an `Rc<T>`. Unlike dereferencing the handle (which gives a `&T`
27+
tied to the handle's lifetime), `value_rc()` gives you an owned `Rc<T>` that can be moved into
28+
closures or stored independently.
29+
30+
```rust
31+
let counter = use_state(|| 0);
32+
let rc_value: Rc<i32> = counter.value_rc();
33+
```
34+
35+
### `into_inner()`
36+
37+
Consumes the handle and returns its two parts: the current value as `Rc<T>` and the
38+
setter/dispatcher. This is useful when you want to separate reading from writing without cloning
39+
the full handle.
40+
41+
For `UseReducerHandle`, the return type is `(Rc<T>, UseReducerDispatcher<T>)`:
42+
43+
```rust
44+
let state = use_reducer(CounterState::default);
45+
let (value, dispatcher) = state.into_inner();
46+
```
47+
48+
For `UseStateHandle`, the return type is `(Rc<T>, UseStateSetter<T>)`:
49+
50+
```rust
51+
let state = use_state(|| 0);
52+
let (value, setter) = state.into_inner();
53+
```
54+
2055
[use_state]: https://yew-rs-api.web.app/next/yew/functional/fn.use_state.html
2156
[use_state_eq]: https://yew-rs-api.web.app/next/yew/functional/fn.use_state_eq.html
2257
[use_reducer]: https://yew-rs-api.web.app/next/yew/functional/fn.use_reducer.html

website/i18n/ja/docusaurus-plugin-content-docs/current/concepts/function-components/state.mdx

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,39 @@ title: '状態'
1717
| [use_mut_ref] | `T` | - | コンポーネントインスタンス内 |
1818
| グローバル静的定数 | `T` | - | グローバル、どこでも使用可能 |
1919

20+
## ハンドルの内部へのアクセス
21+
22+
`UseStateHandle``UseReducerHandle` の両方に、内部パーツに直接アクセスするためのメソッドが用意されています。
23+
24+
### `value_rc()`
25+
26+
現在の値を `Rc<T>` で返します。ハンドルの参照外し(ハンドルのライフタイムに束縛された `&T` を返す)とは
27+
異なり、`value_rc()` はクロージャに移動させたり、独立して保持できる所有された `Rc<T>` を返します。
28+
29+
```rust
30+
let counter = use_state(|| 0);
31+
let rc_value: Rc<i32> = counter.value_rc();
32+
```
33+
34+
### `into_inner()`
35+
36+
ハンドルを消費し、現在の値(`Rc<T>`)とセッター/ディスパッチャーの2つの部分を返します。
37+
ハンドル全体をクローンせずに、読み取りと書き込みを分離したい場合に便利です。
38+
39+
`UseReducerHandle` の場合、返り値の型は `(Rc<T>, UseReducerDispatcher<T>)` です:
40+
41+
```rust
42+
let state = use_reducer(CounterState::default);
43+
let (value, dispatcher) = state.into_inner();
44+
```
45+
46+
`UseStateHandle` の場合、返り値の型は `(Rc<T>, UseStateSetter<T>)` です:
47+
48+
```rust
49+
let state = use_state(|| 0);
50+
let (value, setter) = state.into_inner();
51+
```
52+
2053
[use_state]: https://yew-rs-api.web.app/next/yew/functional/fn.use_state.html
2154
[use_state_eq]: https://yew-rs-api.web.app/next/yew/functional/fn.use_state_eq.html
2255
[use_reducer]: https://yew-rs-api.web.app/next/yew/functional/fn.use_reducer.html

website/i18n/zh-Hans/docusaurus-plugin-content-docs/current/concepts/function-components/state.mdx

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,39 @@ title: '状态'
1717
| [use_mut_ref] | `T` | - | 组件内部实例 |
1818
| 全局静态常量 | `T` | - | 全局,任何位置都可以使用 |
1919

20+
## 访问句柄内部
21+
22+
`UseStateHandle``UseReducerHandle` 都提供了直接访问其内部组成部分的方法。
23+
24+
### `value_rc()`
25+
26+
`Rc<T>` 的形式返回当前值。与对句柄解引用(返回绑定到句柄生命周期的 `&T`)不同,
27+
`value_rc()` 返回一个拥有所有权的 `Rc<T>`,可以移动到闭包中或独立存储���
28+
29+
```rust
30+
let counter = use_state(|| 0);
31+
let rc_value: Rc<i32> = counter.value_rc();
32+
```
33+
34+
### `into_inner()`
35+
36+
消耗句柄并返回其两个组成部分:当前值(`Rc<T>`)和 setter/dispatcher。
37+
当你想要在不克隆整个句柄的情况下将读取与写入分离时,这非常有用。
38+
39+
对于 `UseReducerHandle`,返回类型为 `(Rc<T>, UseReducerDispatcher<T>)`
40+
41+
```rust
42+
let state = use_reducer(CounterState::default);
43+
let (value, dispatcher) = state.into_inner();
44+
```
45+
46+
对于 `UseStateHandle`,返回类型为 `(Rc<T>, UseStateSetter<T>)`���
47+
48+
```rust
49+
let state = use_state(|| 0);
50+
let (value, setter) = state.into_inner();
51+
```
52+
2053
[use_state]: https://yew-rs-api.web.app/next/yew/functional/fn.use_state.html
2154
[use_state_eq]: https://yew-rs-api.web.app/next/yew/functional/fn.use_state_eq.html
2255
[use_reducer]: https://yew-rs-api.web.app/next/yew/functional/fn.use_reducer.html

website/i18n/zh-Hant/docusaurus-plugin-content-docs/current/concepts/function-components/state.mdx

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,39 @@ title: '狀態'
1717
| [use_mut_ref] | `T` | - | 組件內部實例 |
1818
| 全域靜態常數 | `T` | - | 全域,任何位置都可以使用 |
1919

20+
## 存取句柄內部
21+
22+
`UseStateHandle``UseReducerHandle` 都提供了直接存取其內部組成部分的方法。
23+
24+
### `value_rc()`
25+
26+
`Rc<T>` 的形式回傳當前值。與對句柄解參考(回傳繫結到句柄生命週期的 `&T`)不同,
27+
`value_rc()` 回傳一個擁有所有權的 `Rc<T>`,可以移動到閉包中或獨立儲存。
28+
29+
```rust
30+
let counter = use_state(|| 0);
31+
let rc_value: Rc<i32> = counter.value_rc();
32+
```
33+
34+
### `into_inner()`
35+
36+
消耗句柄並回傳其兩個組成部分:當前值(`Rc<T>`)和 setter/dispatcher。
37+
當你想要在不克隆整個句柄的情況下將讀取與寫入分離時,這非常有用。
38+
39+
對於 `UseReducerHandle`,回傳類型為 `(Rc<T>, UseReducerDispatcher<T>)`
40+
41+
```rust
42+
let state = use_reducer(CounterState::default);
43+
let (value, dispatcher) = state.into_inner();
44+
```
45+
46+
對於 `UseStateHandle`,回傳類型為 `(Rc<T>, UseStateSetter<T>)`
47+
48+
```rust
49+
let state = use_state(|| 0);
50+
let (value, setter) = state.into_inner();
51+
```
52+
2053
[use_state]: https://yew-rs-api.web.app/next/yew/functional/fn.use_state.html
2154
[use_state_eq]: https://yew-rs-api.web.app/next/yew/functional/fn.use_state_eq.html
2255
[use_reducer]: https://yew-rs-api.web.app/next/yew/functional/fn.use_reducer.html

0 commit comments

Comments
 (0)