I am trying to update my React application to use MVVM as an architecture pattern. I initially built it out with Hooks and Redux. I've come to find out that every resource I've found uses classes in MVVM. Furthermore, I can't find anything that uses Redux to manage the state. I keep seeing MobX come up, but I am trying to use Redux since I've already got it working and understand it better.
Here is the best resource I've found so far: https://medium.cobeisfresh.com/level-up-your-react-architecture-with-mvvm-a471979e3f21, though ... it's using classes and mobX.
MVVM Architecture (as I've come to understand it)
Model
Holds the state, in my example that would be Redux.
ViewModel
Serves as the middleman between the Model and the ViewController. It handles business logic and has the ability to update the Model.
ViewController
Layer above the view that invokes behaviors derived from the model in response to user actions. Also updates data to be displayed on the view.
View
Dummy component that only displays the data passed in via props or otherwise and renders accordingly.
I have tried breaking the logic out below into something that resembles MVVM and I've been unsuccessful in that endeavor. This component is quite straightforward, it simply reads (<useSelector />
) the state from Redux in a hook and spits out the information in the return statement. The second file is where the output of the first component appears on a screen.
import React from 'react';
import styled from 'styled-components';
import { useSelector } from 'react-redux';
import Skeleton from 'react-loading-skeleton';
import styles, { H300, PSpan } from '../../../ui/styles/variables';
import ProfileImage from '../../ProfileImage/ProfileImage';
const { colors, borders, effects } = styles;
const UserWidget = () => {
const loading = useSelector((state) => state.auth.loading);
const user = useSelector((state) => state.auth.user);
if (loading) {
return (
<Content>
<CustomSkeleton circle height={100} width={100} />
<CustomSkeleton count={4} height={15} width={130} />
</Content>
);
}
return (
<Content className="WIDGET">
<ProfileImage email={user.email} />
<Username>{user.username}</Username>
<UserGlobalStats>
<H300>117,311</H300>
<PSpan>Points</PSpan>
<H300>339</H300>
<PSpan>Words Learned</PSpan>
</UserGlobalStats>
</Content>
);
};
export default UserWidget;
import React from 'react';
import CalendarWidget from '../../../components/_widgets/CalendarWidget/CalendarWidget';
import ModuleHeader from '../../../components/Module/Header/ModuleHeader';
import ModuleBody from '../../../components/Module/Body/ModuleBody';
import ModProgressWidget from '../../../components/_widgets/ModProgressWgt/ModProgressWgt';
import ButtonBlock from '../../../components/_widgets/ButtonBlock/ButtonBlock';
import { Page, LColumn, RColumn } from '../../../ui/styles/layouts';
import UserWidget from '../../../components/_widgets/UserWidget/UserWidget';
const OverviewPage = () => {
return (
<Page>
<LColumn>
<UserWidget /> <------ Here
<CalendarWidget />
</LColumn>
<ModuleHeader difficulty="Beginners" language="French" />
<ModuleBody layout="overview" />
<RColumn>
<ModProgressWidget />
<ButtonBlock />
</RColumn>
</Page>
);
};
export default OverviewPage;
Any help would be appreciated. I really don't want to gut and uproot everything I've been working on to include some different technology. I've seen cryptic answers saying that hooks can be handled through MVVM. Surely redux can be too right?