---
title: '0.22.0 から 0.23.0 へ'
---

import Tabs from '@theme/Tabs'
import TabItem from '@theme/TabItem'

## `use_reducer` が同一ディスパッチで再レンダリングしなくなりました

`use_reducer` はリデューサーが同じ `Rc` を返した場合（ポインタの同一性で判定）、再レンダリングをスキップするようになりました。以前は、すべてのディスパッチで再レンダリングが発生していました。

リデューサーに `self` をそのまま返すコードパスがあり、それによる再レンダリングに依存していた場合は、`use_force_update` に置き換えてください:

<Tabs>
  <TabItem value="before" label="変更前" default>

```rust ,ignore
pub enum Action {
    Increment,
    ForceRefresh,
}

struct State {
    count: u32,
}

impl Reducible for State {
    type Action = Action;

    fn reduce(self: Rc<Self>, action: Self::Action) -> Rc<Self> {
        match action {
            Action::Increment => Rc::new(Self {
                count: self.count + 1,
            }),
            // 0.23 ではこれは再レンダリングを発生させません!
            Action::ForceRefresh => self,
        }
    }
}

#[component]
pub fn App() -> Html {
    use_effect(|| {
        tracing::info!("This cursed component does some effects on render");
    });
    let state = use_reducer(|| State { count: 0 });
    html! {
        <div>
            <p>{ state.count }</p>
            <button onclick={
                let state = state.clone();
                move |_| state.dispatch(Action::Increment)
            }>
                { "+1" }
            </button>
            <button onclick={move |_| state.dispatch(Action::ForceRefresh)}>
                { "リフレッシュ" }
            </button>
        </div>
    }
}
```

  </TabItem>
  <TabItem value="after" label="変更後">

```rust ,ignore
pub enum Action {
    Increment,
}

struct State {
    count: u32,
}

impl Reducible for State {
    type Action = Action;

    fn reduce(self: Rc<Self>, action: Self::Action) -> Rc<Self> {
        match action {
            Action::Increment => Rc::new(Self {
                count: self.count + 1,
            }),
        }
    }
}

#[component]
pub fn App() -> Html {
    use_effect(|| {
        tracing::info!("This cursed component does some effects on render");
    });
    let state = use_reducer(|| State { count: 0 });
    let trigger = use_force_update();
    html! {
        <div>
            <p>{ state.count }</p>
            <button onclick={move |_| state.dispatch(Action::Increment)}>{ "+1" }</button>
            <button onclick={move |_| trigger.force_update()}>{ "リフレッシュ" }</button>
        </div>
    }
}
```

  </TabItem>
</Tabs>
