-
-
Save jonathanwork/9aa96d839b80f4f57ad89ff5c6d07ddb to your computer and use it in GitHub Desktop.
React Redux
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Send a login request to the server to retrieve a JWT token. | |
* @param credentials | |
* @returns {{type: *, isFetching: boolean, isAuthenticated: boolean, credentials: *}} | |
*/ | |
function requestLogin() { | |
return { | |
type: LOGIN_REQUEST, | |
isFetching: true, | |
isAuthenticated: false | |
} | |
} | |
/** | |
* When a successful response is received from the server, sign in the user. | |
* @param token | |
* @returns {{type: *, isFetching: boolean, isAuthenticated: boolean, id_token: *}} | |
*/ | |
function receiveLogin(token) { | |
return { | |
type: LOGIN_SUCCESS, | |
isFetching: false, | |
isAuthenticated: true, | |
token: token | |
} | |
} | |
/** | |
* Handle errors in the sign in flow | |
* @param message - The received error message | |
* @returns {{type: *, isFetching: boolean, isAuthenticated: boolean, message: *}} | |
*/ | |
export function loginError(message) { | |
return { | |
type: LOGIN_FAILURE, | |
isFetching: false, | |
isAuthenticated: false, | |
message: message | |
} | |
} | |
/** | |
* Sign in a user by making an API request and handling the response. Depending on the response, the function will | |
* emit a success or error action which will trigger the reducer to change the state accordingly. | |
* @param credentials | |
* @param success | |
* @returns {Function} | |
*/ | |
export function loginUser(credentials, success) { | |
let body = { | |
"email": credentials.email, | |
"password": credentials.password | |
}; | |
return dispatch => { | |
dispatch(requestLogin()); | |
//Make an API call to the login endpoint containing the users credentials | |
return callApi('POST', PATH_LOGIN, body, state).then(function (response) { | |
//The call was successful. | |
response.json().then(token => ({token, response})) | |
.then(({token, response}) => { | |
dispatch(receiveLogin(token.token)); | |
success(); | |
}).catch(err => console.log("Error: ", err)); | |
}, function (response) { | |
//The endpoint returned an error code. | |
//Here we extract the error, and emit a loginError action containing the message. | |
response.json().then(object => { | |
dispatch(loginError(object.errors[0])); | |
}); | |
}); | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class HomePage extends Component { | |
render() { | |
// isAuthenticated is mapped from the state to the components properties | |
// when the component is connected to the state. | |
const { dispatch, isAuthenticated } = this.props; | |
return ( | |
<div> | |
{/* The user is authenticated, show the profile picture */} | |
{isAuthenticated && | |
<ProfilePicture /> | |
} | |
{/* The user is not authenticated, show the sign in button */} | |
{!isAuthenticated && | |
<SignInButton /> | |
} | |
<Content /> | |
</div> | |
); | |
} | |
} | |
HomePage.propTypes = { | |
dispatch: PropTypes.func.isRequired, | |
isAuthenticated: PropTypes.bool.isRequired | |
}; | |
function mapStateToProps(state) { | |
//Depending on your state's structure, extract the relevant parts | |
//and map them to your properties | |
//In this example we'll just assume we only have a single boolean flag in our state. | |
const isAuthenticated = state; | |
return { | |
isAuthenticated | |
} | |
} | |
// Wrap the component to inject dispatch and state into it | |
export default connect(mapStateToProps)(HomePage); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Reducer to change the application state for all auth state changes | |
* @param state | |
* @param action | |
*/ | |
function auth(state = { | |
isFetching: false, | |
isAuthenticated: false, | |
token: null, | |
errorMessage: "" | |
}, action) { | |
switch (action.type) { | |
case LOGIN_REQUEST: | |
return Object.assign({}, state, { | |
isFetching: true, | |
isAuthenticated: false, | |
errorMessage: "" | |
}); | |
case LOGIN_SUCCESS: | |
return Object.assign({}, state, { | |
isFetching: false, | |
isAuthenticated: true, | |
errorMessage: "", | |
token: action.token | |
}); | |
case LOGIN_FAILURE: | |
return Object.assign({}, state, { | |
isFetching: false, | |
isAuthenticated: false, | |
errorMessage: action.message | |
}); | |
default: | |
return state; | |
} | |
} | |
//When splitting your reducers into separate functions for specific parts of the state | |
//You have combine them into a single reducer function for redux using the combineReducers function. | |
export const reducer = combineReducers({ | |
auth | |
}); | |
export default reducer; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment