@@ -162,3 +162,94 @@ async fn use_reducer_eq_works() {
162162 let result = obtain_result ( ) ;
163163 assert_eq ! ( result. as_str( ) , "3" ) ;
164164}
165+
166+ enum SometimesChangeAction {
167+ /// If this action is sent, the state will remain the same
168+ Keep ,
169+ /// If this action is sent, the state will change
170+ Change ,
171+ }
172+
173+ /// A state that does not implement PartialEq
174+ #[ derive( Clone ) ]
175+ struct SometimesChangingState {
176+ value : i32 ,
177+ }
178+
179+ impl Reducible for SometimesChangingState {
180+ type Action = SometimesChangeAction ;
181+
182+ fn reduce ( self : Rc < Self > , action : Self :: Action ) -> Rc < Self > {
183+ use SometimesChangeAction :: * ;
184+ match action {
185+ Keep => self ,
186+ Change => {
187+ let mut self_: Self = ( * self ) . clone ( ) ;
188+ self_. value += 1 ;
189+ self_. into ( )
190+ }
191+ }
192+ }
193+ }
194+
195+ #[ wasm_bindgen_test]
196+ async fn use_reducer_does_not_rerender_when_rc_is_reused ( ) {
197+ #[ component( UseReducerComponent ) ]
198+ fn use_reducer_comp ( ) -> Html {
199+ let state = use_reducer ( || SometimesChangingState { value : 0 } ) ;
200+ let render_count = use_mut_ref ( || 0 ) ;
201+
202+ let render_count = {
203+ let mut render_count = render_count. borrow_mut ( ) ;
204+ * render_count += 1 ;
205+
206+ * render_count
207+ } ;
208+
209+ let keep_state = {
210+ let state = state. clone ( ) ;
211+ Callback :: from ( move |_| state. dispatch ( SometimesChangeAction :: Keep ) )
212+ } ;
213+
214+ let change_state = Callback :: from ( move |_| state. dispatch ( SometimesChangeAction :: Change ) ) ;
215+
216+ html ! {
217+ <>
218+ <div>
219+ { "This component has been rendered: " } <span id="result" >{ render_count} </span>{ " Time(s)." }
220+ </div>
221+ <button onclick={ keep_state} id="keep-state" >{ "Keep State" } </button>
222+ <button onclick={ change_state} id="change-state" >{ "Change State" } </button>
223+ </>
224+ }
225+ }
226+
227+ yew:: Renderer :: < UseReducerComponent > :: with_root (
228+ document ( ) . get_element_by_id ( "output" ) . unwrap ( ) ,
229+ )
230+ . render ( ) ;
231+ sleep ( Duration :: ZERO ) . await ;
232+
233+ let result = obtain_result ( ) ;
234+ assert_eq ! ( result. as_str( ) , "1" ) ;
235+
236+ document ( )
237+ . get_element_by_id ( "change-state" )
238+ . unwrap ( )
239+ . unchecked_into :: < HtmlElement > ( )
240+ . click ( ) ;
241+ sleep ( Duration :: ZERO ) . await ;
242+
243+ let result = obtain_result ( ) ;
244+ assert_eq ! ( result. as_str( ) , "2" ) ;
245+
246+ document ( )
247+ . get_element_by_id ( "keep-state" )
248+ . unwrap ( )
249+ . unchecked_into :: < HtmlElement > ( )
250+ . click ( ) ;
251+ sleep ( Duration :: ZERO ) . await ;
252+
253+ let result = obtain_result ( ) ;
254+ assert_eq ! ( result. as_str( ) , "2" ) ;
255+ }
0 commit comments