-
Notifications
You must be signed in to change notification settings - Fork 87
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
Question about Dispatching Actions. #67
Comments
Both works. I've seen viewmodels used; personally I just use the codebehind, because I don't need much logic in there for my app (and also I want to make it easy to port from Xamarin.Forms to native Xamarin.Android/iOS for experimentation, which AFAIK do not support data binding out of the box). |
Unless it’s a throwaway prototype, you shouldn’t put any access to the Store into the code-behind. MVVM allows you to write tests that interact with your ViewModel and simulate view interactions without the view by giving you a clear separation of UI from non-UI logic. Communicating with your Store in the code behind is therefore technically an MVVM violation because, without the view, you can’t test this code. MVVM and Redux don’t fit well together because MVVM and bindings break the one-way data flow of Redux/React Architecture. MVVM and bindings also make direct changes to the target property they are bound to on the model, but this is impossible when you have an immutable store with immutable models. A typical pattern you see with MVVM is some data retrieval, via a service or repository data source, in the ViewModel. SOLID and SRP purists would have a problem with this as a ViewModel should only have one responsibility, and that’s to adapt your model to the view. Once your application grows, it makes more sense to keep the logic in the Model and wrap it with a ViewModel when interactions like Commands are required. A possible solution to your question:
This will keep your Store and MVVM cleanly separated, which in my opinion is a good thing, as they are solving two different problems. |
I've moved to F# (not really relevant for this comment) and am using a solution I find very clean and easily testable, which allows for unidirectional data flow of most state while using MVVM/INotifyPropertyChanged for e.g. input field state (which doesn't work well with redux - dispatching every new value of text fields to the store has several problems, e.g. poor performance and chance of triggering infinite loops since you're in a sense setting the text field value from its TextChanged event handler, with no optimal solutions). What I do is this (using a sign-in page as example, and rough pseudocode as I'm writing this from the top of my head and haven't used C# in a while):
class SignInVmData {
SignInVmData(RootState state) {
// The constructor is uninteresting to test since it just maps the redux state
IsSigningIn = state.SignIn.IsSigningIn;
LastSignIn = state.SignIn.LastSignIn;
}
// for easier testing (F# solves this more robustly with less boilerplate)
SignInVmData() { }
public bool IsSigningIn {get; set;}
public DateTimeOffset LastSignIn {get; set;}
}
class SignInVm {
SignInVm(SignInVmData data) {
_data = data;
}
public SignInVmData _data {get; set;}
public DateTimeOffset _now {get; set;} = DateTimeOffset.Now
public string Username {get; set;}
public string Password {get; set;}
public bool InputFieldsEnabled =>
!_data.IsSigningIn;
public bool CanSignIn =>
!string.IsNullOrEmpty(Username)
&& !string.IsNullOrEmpty(Password)
&& !_data.IsSigningIn;
// Fairly pointless thing on a sign-in screen, it's here just to demo the time stuff
public string SecondsSinceLastSignIn =>
(_now - _data.LastSignIn).TotalSeconds.ToString();
public bool SignInAction =>
CanSignIn ? SignInAction(Username, Password) : null;
}
class SignInPage : MyViewBaseClass {
SignInPage(Store store) {
var vm = new SignInVm(new SignInVmData(store.State));
this.BindingContext = vm;
store.StateChanged += state => vm._data = SignInVmData(state)
SomeOnceASecondTimer.Elapsed += () => vm._now = DateTimeOffset.Now
}
} All in all, the advantages are:
|
Hi,
I am working on Xamarin application and have been using MVVM so far. I am now trying to incorporate Redux to manage the state.
My question is, which a good place to call Store.Dispatch()? Should I keep it in code behind of Xaml or viewmodel?
It works either ways, but I want to understand which is a better practice? Should I continue using ViewModels after adopting Redux or just wire the state directly to View?
Thanks
The text was updated successfully, but these errors were encountered: