Action | Files | Exports |
---|---|---|
CREATE | src/modules/user/user.actions.js | {login, logout} |
CREATE | src/modules/user/user.reducer.js | {initialState, userReducer} |
CREATE | src/modules/user/user.context.js | {useUser, useUserState, useUserDispatch, UserProvider} |
CREATE | src/modules/user/user.hook.js | {usePersistedUser} |
CREATE | src/modules/user/user.selectors.js | {getUser, isConnectedUser} |
CREATE | src/modules/user/components/login.component.js | {Login} |
CREATE | src/pages/login.page.js | {LoginPage} |
CREATE | src/pages/checkout.page.js | {CheckoutPage} |
CREATE | src/modules/routing/routing.hooks.js | {useLoginRedirect} |
CREATE | src/modules/routing/routing.constants.js | {ROUTES_PATHS_BY_NAMES, PROTECTED_PATHS} |
CREATE | src/modules/routing/components/routes.component.js | {AppRoutes} |
MODIFY | src/App.js | {App} |
MODIFY | src/modules/articles/components/articleCard.component.js | {ArticleCard} |
It's raining modules, let's create the user, checkout and routing ones !
We need a Checkout page but the user must be logged in to access it. So we also need a Login page. We'll mock the user api and authentication process for now. We need to be redirected to the login page but only from the checkout page.
To begin with, let's duplicate the articles modules and rename it user, it should be pretty step forward to adapt it.
We need a login action creator, a thunk in this case.
/**
*
* @param {string} email
* @param {string} password
*/
export const login = (email, password) => async dispatch => {};
You need to:
- await a call from signIn API method with email and password as parameters to get the user value.
- Set the user in the localStorage under the key "user"
- return dispatch the LOGIN action type
export const logout = () => async (dispatch, getState) => {};
You need to:
- get the user value from the store using the getUser selector and getState
- call the signOut methods othe the API
- Remove the user from the localStorage
- return dispatch the LOGOUT action type with user as property
Super dummy reducer !
Catch the action LOGIN in a case (switch) and set user in the state from the action.user property
Catch the action in a case (switch) LOGOUT and set user in the state to null
Dummy hook !
Returns the user from localStorage
Takes the user context state as parameter and returns a boolean wether it is truthy or not.
Takes the user context state as parameter and returns the user entry from it.
Create a stateful hook that returns the state value (input) and an onChange handler. Basically you would use a control input this way
export const MyForm = () => {
// input type text expects a string
const [inputValue, setInputValue] = useState('');
const onChange = event => setInputValue(event.target.value);
...
};
- Get dispatch from user context
- Integrate two useInput to control email and password TextFields
- Create a submit handler for the form that dispatch the login action with the email and password
- Create a classic page and add the Login component under the habitual layout.
Let's do a clean enum for our routes and for our protected routes.
Create an enum of routePathsByNames
export const ROUTES_PATHS_BY_NAMES = {
foo: '/foo',
};
Create an enum of routePathsByNames
export const PROTECTED_PATHS = [ROUTES_PATHS_BY_NAMES.checkout];
The main course of this exercise ! You need to figure out how to redirect the user whenever he is not logged in when he tries to access the checkout page.
You'll need to use react-router-dom
useLocation for pathname
checks and useHistory to get the push
method.
This hook will only perform side effects, it will not return any value. It will use state and useEffects.
Good luck.