Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Reliable use_reducer dispatch and use_state setter #2126

Merged
merged 14 commits into from
Nov 11, 2021
Merged

Reliable use_reducer dispatch and use_state setter #2126

merged 14 commits into from
Nov 11, 2021

Conversation

futursolo
Copy link
Member

@futursolo futursolo commented Oct 31, 2021

Description

As described in #2112, use_state's value is susceptible to outdated values and causes the set_if_neq to be unreliable.

The reducer function is also susceptible to the same problem as it is tied to the dispatch function with the current implementation.

The value going stale problem mostly can be solved by adapting established patterns from the React world but it still requires the setter and dispatch function to work reliably (Or functions like their counterpart in React).

This PR takes a different approach which makes the reducer function to be static to avoid it becoming stale or attempting to pass a different reducer function between renders.
(Defining the reducer function outside of the component is a common practice in React and attempting to update another state while the component is rendering will result in an error in React.)

This PR consists of the following change:

  • use_reducer now accepts 1 argument which is an initialiser function.
  • The State of use_reducer now requires to implement Reducible trait which provides Action and reduce.
  • Added use_reducer_eq which only re-renders if prev_state != next_state.
  • use_state is implemented with use_reducer.
  • Added use_state_eq which only re-renders if prev_state != next_state (Implemented with use_reducer_eq).
  • UseStateHandle and UseReducerHandle only implements PartialEq if T: PartialEq.
  • A set-only and dispatch-only handle can be detached from the original handle by calling the dispatcher and setter method. It always implements PartialEq even if T: !PartialEq. This can be passed as a prop / context if T is not PartialEq.

Fixes #2112 (in conjunction with #2125).

Checklist

  • I have run cargo make pr-flow
  • I have reviewed my own code
  • I have added tests

@github-actions
Copy link

github-actions bot commented Oct 31, 2021

Visit the preview URL for this PR (updated for commit f800148):

https://yew-rs--pr2126-stale-value-ptcefc0e.web.app

(expires Thu, 18 Nov 2021 11:28:23 GMT)

🔥 via Firebase Hosting GitHub Action 🌎

@futursolo
Copy link
Member Author

futursolo commented Oct 31, 2021

Old Approach:

struct CounterState {
    counter: i32,
}

let counter = use_reducer_with_init(
    |prev: std::rc::Rc<CounterState>, action: i32| CounterState {
        counter: prev.counter + action,
    },
    0,
    |initial: i32| CounterState {
        counter: initial + 10,
    },
);

New Approach:

struct CounterState {
    counter: i32,
}

impl Default for CounterState {
    fn default() -> Self {
        Self { counter: 10 }
    }
}

impl Reducible for CounterState {
    type Action = i32;

    fn reduce(self: Rc<Self>, action: Self::Action) -> Rc<Self> {
        Self {
            counter: self.counter + action,
        }
        .into()
    }
}

let counter = use_reducer(CounterState::default);

@futursolo futursolo mentioned this pull request Oct 31, 2021
3 tasks
voidpumpkin
voidpumpkin previously approved these changes Nov 11, 2021
Copy link
Member

@voidpumpkin voidpumpkin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good!

@voidpumpkin voidpumpkin added A-yew Area: The main yew crate A-examples Area: The examples labels Nov 11, 2021
Copy link
Member

@siku2 siku2 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just some documentation grammar

@voidpumpkin voidpumpkin added the S-waiting-on-author Status: awaiting action from the author of the issue/PR label Nov 11, 2021
@futursolo futursolo requested a review from siku2 November 11, 2021 11:18
@siku2 siku2 merged commit 706fb48 into yewstack:master Nov 11, 2021
@voidpumpkin voidpumpkin removed the S-waiting-on-author Status: awaiting action from the author of the issue/PR label Nov 26, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-examples Area: The examples A-yew Area: The main yew crate
Projects
None yet
Development

Successfully merging this pull request may close these issues.

UseStateHandle can become stale
3 participants