# Flux vs. MVVM Architecture ## Decision Matrix: Flux vs. MVVM | Criterion | Plain Effector (Flux) | MVVM Layer on Top | |-----------|----------------------|-------------------| | Boilerplate | Low | Higher | | React Ecosystem Fit | Native | Non-idiomatic | | Two-way Binding Risk | None | Possible | | Testability | High (domain files are pure) | High but more layers | | Refactor Complexity | Lower | Higher | ## Why We Chose Flux with Effector For our React SPA, we've adopted an "Effector-based Flux architecture" for the following reasons: 1. **Better React Integration**: Flux's unidirectional data flow aligns perfectly with React's rendering model. 2. **Simplicity**: Fewer abstractions and less boilerplate compared to MVVM. 3. **Predictability**: One-way data flow makes it easier to trace how state changes propagate through the application. 4. **Testability**: Pure functions in model.ts are easy to test without complex mocking. 5. **TypeScript Friendly**: Effector has excellent TypeScript support, providing type safety throughout the application. ## Flux Architecture Flow ``` ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ Actions │────>│ Store │────>│ View │ │ (Events) │ │ (State) │ │ (React) │ └─────────────┘ └─────────────┘ └─────────────┘ ▲ │ │ │ └───────────────────────────────────────┘ User Interaction ``` ## Effector Implementation Effector provides three main primitives that map to Flux concepts: 1. **Events** (Actions): Trigger state changes ```typescript export const setProductName = createEvent(); ``` 2. **Stores** (State): Hold application state ```typescript export const $product = createStore(initialState) .on(setProductName, (state, name) => ({ ...state, name })); ``` 3. **Effects** (Async Actions): Handle side effects ```typescript export const fetchProductFx = createEffect(async (id: string) => { return await api.getProduct(id); }); ``` ## Conclusion While MVVM is a valid architecture pattern, Flux with Effector provides a more natural fit for React applications, with less boilerplate and better alignment with React's unidirectional data flow model. This approach keeps our codebase clean, testable, and maintainable.