<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Ethan Soo Hon</title>
    <description>The latest articles on DEV Community by Ethan Soo Hon (@ethanny2).</description>
    <link>https://dev.to/ethanny2</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F313215%2Ff3c9eaff-d56f-4b89-9a11-13e8a19f51b0.jpeg</url>
      <title>DEV Community: Ethan Soo Hon</title>
      <link>https://dev.to/ethanny2</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/ethanny2"/>
    <language>en</language>
    <item>
      <title>Writing your 1st Custom Hook</title>
      <dc:creator>Ethan Soo Hon</dc:creator>
      <pubDate>Mon, 22 Feb 2021 18:19:20 +0000</pubDate>
      <link>https://dev.to/ethanny2/writing-your-1st-custom-hook-499</link>
      <guid>https://dev.to/ethanny2/writing-your-1st-custom-hook-499</guid>
      <description>&lt;p&gt;We've all heard of "custom hooks" before but many people still learning React find them intimidating (speaking from personal experience!) and it's hard to see the benefit without a concrete example.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frs0begrilstuqbepyusv.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frs0begrilstuqbepyusv.gif" alt="Confused Gif"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In this tutorial we will first attempt to solve a problem without using a custom hook then we will refactor the code to use a custom hook and see how much cleaner and how much less code there actually is.&lt;/p&gt;

&lt;h2&gt;
  
  
  Semantic UI
&lt;/h2&gt;

&lt;p&gt;For this tutorial we will use the react component library &lt;a href="https://react.semantic-ui.com/" rel="noopener noreferrer"&gt;Semantic UI&lt;/a&gt;. No particular reason, I have just been using it lately and it is relatively simple. After running create-react-app these are our only 2 dependencies&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$  yarn add semantic-ui-react semantic-ui-css
## Or NPM
$  npm install semantic-ui-react semantic-ui-css
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To quickly bootstrap our project so we can get on with writing our custom hook let's grab a layout example from their site.&lt;/p&gt;

&lt;center&gt;
![Example screen](https://i.gyazo.com/b3bd5a64368f11e469ea481c0eba3913.png)
*[Link to page](https://react.semantic-ui.com/layouts/login)*
&lt;/center&gt;



&lt;p&gt;This resulting layout is achieved with Semantic UI components in about 30 lines. We will take this code and make a Login.js component.&lt;/p&gt;

&lt;p&gt;We'll place our Login in our App.js and don't forget the import line for the minified stylesheet or else the library won't work!&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import './App.css';
import Login from './Login.js';
import 'semantic-ui-css/semantic.min.css'

function App() {
  return (
    &amp;lt;main&amp;gt;
      &amp;lt;Login&amp;gt;&amp;lt;/Login&amp;gt;
    &amp;lt;/main&amp;gt;
  );
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Goal
&lt;/h2&gt;

&lt;p&gt;We'll try to keep the problem as simple as possible; we want an alert/message to be transitioned in at the top of the screen when a user's login fails or succeeds. In addition, we want for that message to timeout after a specific amount of time. This form is not connected to anything so to emulate a login failing (by network issues, incorrect credentials etc...) or succeeding we use Math.random() each time the form is submitted.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/* Inside Login.js*/
&amp;lt;Form
   size='large'
   onSubmit={(e) =&amp;gt; {
      e.preventDefault();
      const RANDOM_FAILURE = Math.random();
      if (RANDOM_FAILURE &amp;gt;= 0.5) {
         console.log('Login Succeeded');
      } else {
        console.log('Login failed');                
       }
   }}
   &amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Message Component + API
&lt;/h3&gt;

&lt;p&gt;Semantic UI comes with a Message component that looks like the perfect candidate for a pop-up message. &lt;/p&gt;

&lt;center&gt;
![Message Component](https://i.gyazo.com/da35a83a85a17ba213e7f227d97497cf.png)
*[Link to page](https://react.semantic-ui.com/collections/message/#types-message)*
&lt;/center&gt;



&lt;p&gt;Looking at the props we can see that the Message component needs the following props in order to be customized...&lt;br&gt;
&lt;strong&gt;Note:&lt;/strong&gt; As seen below some of the props here do the same thing so we only need one of them.&lt;/p&gt;

&lt;center&gt;
![Message Component](https://i.gyazo.com/1057565bdb6511fdbe6cd5c178ec80d3.png)
*Redundant props success &amp;amp; positive, negative &amp;amp; error and hidden and visible*
&lt;/center&gt;


&lt;h3&gt;
  
  
  Transition Component + API
&lt;/h3&gt;

&lt;p&gt;We also want to transition the message in smoothly with a CSS animation. We could do it manually but Semantic UI also comes with a Transition component that does it for us if we wrap around our it around our Message. This way we can specify the animation we want as a string prop. Here's a basic example&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   &amp;lt;Transition
        duration={2000}
        animation="scale"
        visible={false}
        unmountOnHide={true}&amp;gt;
     &amp;lt;p&amp;gt; Hello World! &amp;lt;/p&amp;gt;
&amp;lt;/Transition&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The transition component will only trigger when its visible prop is changed from false to true or vice-versa. You &lt;strong&gt;Cannot&lt;/strong&gt; just do visible={true} and expect it to work.&lt;/p&gt;

&lt;h3&gt;
  
  
  Attempt 1
&lt;/h3&gt;

&lt;p&gt;First let's make our local state for the message and transition. We will set the Message component as always visible (props visible={true} and hidden={false}) and let the Transition component wrapped around it handle the visibility.  We then create our piece of state (using an object) and fill it will all the info that we need to customize our Message via props.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
  const [messageConfig, setmessageConfig] = useState({
    visible: false,
    header: "",
    content: "",
    error: false,
    success: false,
  });
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Okay nows let's pass the properties from this state object into our Components! Notice in the onDismiss for our Message (a required prop) we just hide the message and set the state back to the default values.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;            &amp;lt;Transition
                duration={2000}
                animation='scale'
                visible={messageConfig.visible}
                unmountOnHide={true}
            &amp;gt;
                &amp;lt;Message
                    onDismiss={() =&amp;gt; {
                    setmessageConfig({
                            header: '',
                            content: '',
                            error: false,
                            success: false,
                            visible: false
                        });
                    }}
                    compact
                    size='large'
                    content={messageConfig.content}
                    header={messageConfig.header}
                    error={messageConfig.error}
                    success={messageConfig.success}
                    visible={true}
                    hidden={false}
                &amp;gt;

                &amp;lt;/Message&amp;gt;
            &amp;lt;/Transition&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now that we have everything setup we just need to call our setMessageConfig whenever we want to see a message and then create a setTimeout() to hide the message after a specific period of time (let's say 2s).&lt;/p&gt;

&lt;p&gt;Here's our onSubmit from before now with the newly added code&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    onSubmit={(e) =&amp;gt; {
                            e.preventDefault();
                            const RANDOM_FAILURE = Math.random();
                            console.log(RANDOM_FAILURE);
                            if (RANDOM_FAILURE &amp;gt;= 0.5) {
                                console.log('Login Succeeded');
                                setmessageConfig({
                                    header: 'Success',
                                    content: 'Login Successfull',
                                    error: false,
                                    success: true,
                                    visible: true
                                });
                                setTimeout(() =&amp;gt; {
                                    setmessageConfig({
                                        header: '',
                                        content: '',
                                        error: false,
                                        success: true,
                                        visible: false
                                    });
                                }, 2000);
                            } else {
                                console.log('Login failed');
                                setmessageConfig({
                                    header: 'Failure',
                                    content: 'Login Failed',
                                    error: false,
                                    success: true,
                                    visible: true
                                });
                                setTimeout(() =&amp;gt; {
                                    setmessageConfig({
                                        header: '',
                                        content: '',
                                        error: false,
                                        success: true,
                                        visible: false
                                    });
                                }, 2000);
                            }
                        }}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;center&gt;
![Working Message](https://i.gyazo.com/e97fe65c33c2e87e9207db775fac6bd6.png)
*Technically it works... but we can do better*
&lt;/center&gt;



&lt;p&gt;It works... but look at all the code we have to type everytime we need to show and autoHide a message. Let's try to refactor it into a custom hook.&lt;/p&gt;

&lt;h3&gt;
  
  
  Custom Hook rules
&lt;/h3&gt;

&lt;p&gt;These are paraphrased directly from the &lt;a href="https://reactjs.org/docs/hooks-custom.html" rel="noopener noreferrer"&gt;React docs&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;1) The code written by the custom hook will be functionally equivalent to what we have now. The advantage of refactoring is having a cleaner, easier to understand code base and reusable logic.&lt;/p&gt;

&lt;p&gt;2) Name your custom hooks function by the React convention (useSomething). Is it required? No. But it is a very important convention for others you will potentially share the hook/codebase with.&lt;/p&gt;

&lt;p&gt;3) Components using the same custom hook do not share state variables; the state variables defined in custom hooks are fully isolated.&lt;/p&gt;

&lt;h3&gt;
  
  
  Writing the hook
&lt;/h3&gt;

&lt;p&gt;A custom hook is just a function; the thing that makes it a &lt;em&gt;custom hook&lt;/em&gt; is its use of built-in React hooks functions (useState, useEffect etc...) and reusable logic. I defined an object to hold the initial state of our message just for convenience.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { useState } from 'react';
const INITIAL_STATE = {
    header: '',
    content: '',
    error: false,
    success: false,
    visible: false
};
function useMessage(autoHideDuration = 2000) {
    const [messageConfig, setmessageConfig] = useState(INITIAL_STATE);
    function showMessage(config = { ...INITIAL_STATE }) {
        setmessageConfig({ ...config, visible: true });
        setTimeout(() =&amp;gt; {
            hideMessage();
        }, autoHideDuration );
    }
    function hideMessage() {
        setmessageConfig({...INITIAL_STATE});
    }
    return [showMessage, hideMessage, messageConfig];
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;All we did here was&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Name our function according to hook rules. We take in an 
argument here to determine the delay before the message hides.
Your custom hook can take in arguments or not, up to you.&lt;/li&gt;
&lt;li&gt;Take the defined state object in Login.js and move it in here.&lt;/li&gt;
&lt;li&gt;Create two helper functions to manipulate the state so when
we are using the hook we don't have call the setter or the 
setTimeout directly making it cleaner and easier to use.&lt;/li&gt;
&lt;li&gt;showMessage takes in the config from the user, sets visible 
to true, and then initiates a setTimeout that hides the
Message after the period is over.&lt;/li&gt;
&lt;li&gt;There is no &lt;em&gt;strict&lt;/em&gt; rule that states what should be returned 
from a custom hook needs to be in an array, but most people 
follow the return pattern used by useState and return an 
array of multiple values we can destructure to access.
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Using the custom hook
&lt;/h3&gt;

&lt;p&gt;We removed the state messageConfig from Login.js and replaced it with our custom hook.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const [showMessage, hideMessage, messageConfig] = useMessage(2500);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here's how our onSubmit now looks!&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;onSubmit={(e) =&amp;gt; {                           
  e.preventDefault();                            
  const RANDOM_FAILURE = Math.random();                          
  if (RANDOM_FAILURE &amp;gt;= 0.5) {                               
    showMessage({                                
       header: 'Success',                                
       content: 'Login Successful',                          
       error: false,                         
       success: true,
       visible: true                         
    });
  } else {                               
     showMessage({                               
       header: 'Failure',                                
       content: 'Login Failed',                              
       error: true,                              
       success: false,                               
      visible: true                          
    });
}
}}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;center&gt; *Wayyyyy better* 😄&lt;/center&gt;



&lt;p&gt;Here's the final version; have fun writing custom hooks!&lt;/p&gt;

&lt;p&gt;&lt;iframe src="https://codesandbox.io/embed/q9j4g"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;*Cover image Credit : &lt;a href="https://morioh.com/p/92aa46de9b85" rel="noopener noreferrer"&gt;Link to Image&lt;/a&gt;&lt;/p&gt;

</description>
      <category>react</category>
      <category>hooks</category>
      <category>javascript</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Let's Make a Redux + Material UI + OAuth Starter template! Pt 4. Navbar &amp; Theme Switch</title>
      <dc:creator>Ethan Soo Hon</dc:creator>
      <pubDate>Sun, 21 Feb 2021 19:36:22 +0000</pubDate>
      <link>https://dev.to/ethanny2/let-s-make-a-redux-material-ui-oauth-starter-template-pt-4-navbar-theme-switch-1f7i</link>
      <guid>https://dev.to/ethanny2/let-s-make-a-redux-material-ui-oauth-starter-template-pt-4-navbar-theme-switch-1f7i</guid>
      <description>&lt;p&gt;In the last part of this tutorial series we will set up a mobile responsive Navbar component that has a theme switcher and the user's profile details once they're logged in.&lt;/p&gt;

&lt;h2&gt;
  
  
  AppBar
&lt;/h2&gt;

&lt;center&gt;
![Appbar docs](https://i.gyazo.com/56f37bdfc4aaf58467df8e090e923fe2.png)

*Material UI Docs*
&lt;/center&gt;



&lt;p&gt;On this same documentation page they have many examples of built NavBars; we will take the sample code for the &lt;a href="https://material-ui.com/components/app-bar/#PrimarySearchAppBar.js" rel="noopener noreferrer"&gt;&lt;strong&gt;App Bar with a primary search field&lt;/strong&gt;&lt;/a&gt; example and modify it to suit our needs.The good news is that we finished setting up the redux store in the previous article (so we don't have to add any additional code); the bad news is the NavBar code seems rather complex at first glance, so let's walk through it together!&lt;/p&gt;

&lt;center&gt;
![AppBar with search](https://i.gyazo.com/cd4c5da46509a6f2ef6fd899a054b66f.png
)

*Our starting point*
&lt;/center&gt;



&lt;h2&gt;
  
  
  Breaking down our NavBar.js
&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;1) Styles&lt;/em&gt;:&lt;br&gt;
From our example code we copied from the documentation we see that that this particular AppBar has a search bar and a hamburger icon on the far left. We don't need the search bar or the hamber icon so we will remove the styles for those and add in additional styles for...  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;theme switch (themeToggle)
&lt;/li&gt;
&lt;li&gt;image container for the user's photo (imageContainer) &lt;/li&gt;
&lt;li&gt;nav ruleset to change the backgroundColor. (nav)
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
const useStyles = makeStyles((theme) =&amp;gt; ({
  grow: {
    flexGrow: 1,
  },
  title: {
    display: 'none',
    [theme.breakpoints.up('sm')]: {
      display: 'block',
    },
  },
  sectionDesktop: {
    display: 'none',
    [theme.breakpoints.up('md')]: {
      display: 'flex',
    },
  },
  sectionMobile: {
    display: 'flex',
    [theme.breakpoints.up('md')]: {
      display: 'none',
    },
  },
    nav: {
        backgroundColor: theme.palette.primary.main,
        color: theme.palette.primary.contrastText
    },
    themeToggle: {
        [theme.breakpoints.up('sm')]: {
            padding: 0
        }
    },
    imageContainer: {
        maxWidth: '100%',
        height: 'auto',
        '&amp;amp; img': {
            width: '2em'
        }
    }
}));

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;center&gt; *We removed inputInput, inputRoot , searchIcon, search and menuButton properties* &lt;/center&gt;



&lt;p&gt;The rest is fairly simple; the syntax of the Material UI makeStyles hook allows you to easily set nested properties (Like in SASS/SCSS) AND set up media queries. We didn't explicitly set our own breakpoints when making a custom theme so they are inherited from the default theme.&lt;/p&gt;

&lt;center&gt;
![Breakpoint docs](
https://i.gyazo.com/f7f533ed5d6f67915f7a0f5916eae78f.png)

*Default breakpoint values*
&lt;/center&gt;



&lt;p&gt;&lt;strong&gt;2) Local State and Theme Switch&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;There are lots of state variables and functions in the example component; let's determine what they do.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; The example also had a submenu on desktop as well, but I chose to remove it to simplify the code. This means we deleted the following...&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  const [anchorEl, setAnchorEl] = React.useState(null);&lt;/li&gt;
&lt;li&gt;  const isMenuOpen = Boolean(anchorEl);&lt;/li&gt;
&lt;li&gt;handleProfileMenuOpen,handleProfileMenuClose functions&lt;/li&gt;
&lt;li&gt;renderMenu variable
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const [mobileMoreAnchorEl, setMobileMoreAnchorEl] = React.useState(null); 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;To enable mobile responsiveness we will have a submenu pop up when the width of the device is too small to fit all items in the default nav bar. This will be done with the &lt;a href="https://material-ui.com/components/menus/#simple-menu" rel="noopener noreferrer"&gt;Material UI Menu component&lt;/a&gt;. The prop anchorEl (which takes in a DOM node) determines where the menu will appear on the screen. &lt;/p&gt;

&lt;p&gt;When the user clicks on our mobile menu icon &lt;strong&gt;handleMobileMenuOpen&lt;/strong&gt; will be called. We have a variable setup to coerce the value of mobileMoreAnchorEl to a boolean. If it's still the default null value this will evaluate to false. If there is a DOM element in mobileMoreAnchorEl then we know they clicked it and want to open the mobile menu.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    const isMobileMenuOpen = Boolean(mobileMoreAnchorEl);

    /*The anchor pieces of state need to either be null or have a DOM element */
    const handleMobileMenuOpen = (event) =&amp;gt; {
        setMobileMoreAnchorEl(event.currentTarget);
    };
    const handleMobileMenuClose = () =&amp;gt; {
        setMobileMoreAnchorEl(null);
    };
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;center&gt; *To close it we just set state back to null* &lt;/center&gt;



&lt;h4&gt;
  
  
  renderMobileMenu
&lt;/h4&gt;

&lt;p&gt;This variable contains the JSX for our sub-menu on mobile; The menu is made with the Material UI menu component. We will mostly leave this menu as-is but feel free to play with the Icon / badge content to change the # of notifications or emails etc...&lt;/p&gt;

&lt;p&gt;The one thing we want to add here is a toggle to switch the theme; luckily Material UI also has a component for that &lt;/p&gt;

&lt;center&gt;
![Switch docs](
https://i.gyazo.com/af999c8ee8d7266b822958a1b1125374.png)

*[Just what we need!](https://material-ui.com/components/switches/#Switches.js)*
&lt;/center&gt;



&lt;p&gt;The basic example is sufficient enough we just have to supply a few props. The most important being the checked boolean and the onChange function.&lt;/p&gt;

&lt;p&gt;For the switch I decided true=dark mode (no particular reason) so we reach in to the redux store with useSelector and grab our theme object. If the theme.palette type is "dark" checked is true. onChange when clicked will dispatch our toggleTheme action creator we made in article 3 and voila we have a working theme button!&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    const { auth, theme } = useSelector((state) =&amp;gt; state);
const renderMobileMenu = (
        &amp;lt;Menu
            anchorEl={mobileMoreAnchorEl}
            anchorOrigin={{ vertical: 'top', horizontal: 'right' }}
            id={mobileMenuId} 
            keepMounted
            transformOrigin={{ vertical: 'top', horizontal: 'right' }}
            open={isMobileMenuOpen}
            onClose={handleMobileMenuClose}
        &amp;gt;
            &amp;lt;MenuItem&amp;gt;
                &amp;lt;IconButton aria-label='show 1 new mails' color='inherit'&amp;gt;
                    &amp;lt;Badge badgeContent={1} color='secondary'&amp;gt;
                        &amp;lt;MailIcon /&amp;gt;
                    &amp;lt;/Badge&amp;gt;
                &amp;lt;/IconButton&amp;gt;
                &amp;lt;p&amp;gt;Messages&amp;lt;/p&amp;gt;
            &amp;lt;/MenuItem&amp;gt;
...
...
...
&amp;lt;MenuItem&amp;gt;
                &amp;lt;IconButton aria-label='toggle dark mode'&amp;gt;
                    &amp;lt;Switch
                        color='default'
                        checked={theme.palette.type === 'dark'}
                        onChange={() =&amp;gt; dispatch(toggleTheme())}
                        inputProps={{ 'aria-label': 'primary checkbox' }}
                        name='themeToggle'
                    &amp;gt;&amp;lt;/Switch&amp;gt;
                &amp;lt;/IconButton&amp;gt;
                &amp;lt;p&amp;gt;Theme &amp;lt;/p&amp;gt;
            &amp;lt;/MenuItem&amp;gt;
    &amp;lt;/Menu&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;center&gt;*id here is just a string; we use it for ARIA support. Our mobile button to bring up the submenu should have an aria-controls prop equal to this ID*&lt;/center&gt;



&lt;p&gt;&lt;strong&gt;3) The returned JSX&lt;/strong&gt;&lt;br&gt;
Again we are mostly keeping the code from &lt;strong&gt;App Bar with a primary search field&lt;/strong&gt; the only thing we add to the Navbar is the users profile picture, the switch for toggling the theme and conditional rendering dependent on the user's login status.&lt;/p&gt;

&lt;p&gt;Here are the components wrapping the navbar...&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;return (
 &amp;lt;header className={classes.grow}&amp;gt;
  &amp;lt;AppBar position='static' component='div'&amp;gt;
   &amp;lt;Toolbar component='nav' className={classes.nav}&amp;gt;
    &amp;lt;Typography className={classes.title} variant='h6' noWrap&amp;gt;
     Google Oauth Redux
    &amp;lt;/Typography&amp;gt;
    &amp;lt;div className={classes.grow} /&amp;gt;
    ...
    ...
    ...
)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Within the above components we have the following two divs that separate the content that will render in the navbar on desktop widths and mobile widths. We add the conditional rendering in there.&lt;br&gt;
&lt;strong&gt;Note: The JSX in the sectionMobile div is JUST FOR THE ICON/BUTTON to open the submenu (see renderMobileMenu variable)&lt;/strong&gt;&lt;/p&gt;
&lt;h5&gt;
  
  
  Desktop NavBar items
&lt;/h5&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    &amp;lt;div className={classes.sectionDesktop}&amp;gt;
    {auth.user ? &amp;lt;&amp;gt;
        /* ...Mail &amp;amp; Notification IconButtons */
          &amp;lt;IconButton aria-label='toggle dark mode'&amp;gt;
           &amp;lt;Switch                               
                  color='default'                                        
                  checked={theme.palette.type === 'dark'}                                    
                  onChange={() =&amp;gt; dispatch(toggleTheme())}                               
                  inputProps={{ 'aria-label': 'primary checkbox' }}                                      
                  name='themeToggle'                                
           &amp;lt;/Switch&amp;gt;                
          &amp;lt;/IconButton&amp;gt;
          &amp;lt;IconButton
              edge='end'                         
              aria label='account of current user'                   
              aria-haspopup='true'                               
              color='inherit'
          &amp;gt;
         &amp;lt;div className={classes.imageContainer}&amp;gt;                                
               &amp;lt;img src={auth.user.imageUrl} alt={auth.user.givenName} /&amp;gt;                                    
             &amp;lt;/div&amp;gt; 
          &amp;lt;/IconButton&amp;gt;
       &amp;lt;/&amp;gt; : &amp;lt;p&amp;gt;Not Logged in &amp;lt;/p&amp;gt;}
      &amp;lt;div/&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h5&gt;
  
  
  Mobile NavBar items
&lt;/h5&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import MoreIcon from '@material-ui/icons/MoreVert';

&amp;lt;div className={classes.sectionMobile}&amp;gt;
  {auth.user ? &amp;lt;&amp;gt;
    &amp;lt;IconButton                                  
       aria-label='show more'                                
       aria-controls={mobileMenuId}                              
       aria-haspopup='true'                              
       onClick={handleMobileMenuOpen}                                
       color='inherit'
      &amp;gt;                              
        &amp;lt;MoreIcon /&amp;gt;                         
      &amp;lt;/IconButton&amp;gt;
  &amp;lt;/&amp;gt;:  &amp;lt;p&amp;gt;Not Logged in &amp;lt;/p&amp;gt;}

&amp;lt;/div&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Finally at the very end we throw in the variable renderMobileMenu (it's not a function, just JSX) because the menu is always being rendered (even if we're not on mobile or have not opened it) but only visible to us when we click the button that triggers a state change and causes the open prop be true.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;header&amp;gt;
   &amp;lt;AppBar&amp;gt; 
    &amp;lt;Toolbar&amp;gt;
    ...
    ...
    &amp;lt;/Toolbar&amp;gt;
   &amp;lt;/AppBar&amp;gt;
   {renderMobileMenu}
&amp;lt;/header&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Done 👍
&lt;/h2&gt;

&lt;p&gt;If you have followed this 4 part series you should now have a very reasonable starting template for bootstrapping your front-end projects! &lt;/p&gt;

&lt;p&gt;&lt;a href="https://redux-oauth.netlify.app/" rel="noopener noreferrer"&gt;Here's a full working version&lt;/a&gt; and &lt;a href="https://github.com/ethanny2/redux-material-ui-Oauth-starter" rel="noopener noreferrer"&gt;the repo to the completed code&lt;/a&gt;; please let me know what you think!&lt;/p&gt;

&lt;p&gt;&lt;em&gt;(Be sure to also read the Gotchas section in the Git repo)!&lt;/em&gt;&lt;/p&gt;

</description>
      <category>react</category>
      <category>tutorial</category>
      <category>javascript</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Let's Make a Redux + Material UI + OAuth Starter template! Pt 3. Alerts &amp; Themes</title>
      <dc:creator>Ethan Soo Hon</dc:creator>
      <pubDate>Sat, 20 Feb 2021 18:52:34 +0000</pubDate>
      <link>https://dev.to/ethanny2/let-s-make-a-redux-material-ui-oauth-starter-template-pt-3-alerts-themes-213l</link>
      <guid>https://dev.to/ethanny2/let-s-make-a-redux-material-ui-oauth-starter-template-pt-3-alerts-themes-213l</guid>
      <description>&lt;p&gt;In this part of the series we will examine how to build an alert and theme system controlled by the redux store that you can use across your entire app. Although our buttons do change (due to conditional rendering) if someone interacts with your site it's always a good idea to let the user know if their actions went through successfully or failed!&lt;/p&gt;

&lt;center&gt;![Different types of alerts](https://miro.medium.com/max/6800/1*R4lNMpEdY0VOD96MtkLx4g@2x.png) 
*Different libraries have different names for them but they serve the same purpose*
&lt;/center&gt;



&lt;h2&gt;
  
  
  Snackbar
&lt;/h2&gt;

&lt;p&gt;In the case of the Material UI component library they named this component &lt;strong&gt;Snackbar&lt;/strong&gt;.&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fi.gyazo.com%2F02137e499dd0e5e0681ce34abaa78022.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fi.gyazo.com%2F02137e499dd0e5e0681ce34abaa78022.png" alt="Docs"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;All of the conditions listed in this description are achievable by passing in some props to the Snackbar component. Typically Snackbars are displayed on the bottom of the screen but through you can modify the position with the &lt;em&gt;anchorOrigin&lt;/em&gt; prop. See the &lt;a href="https://material-ui.com/api/snackbar/" rel="noopener noreferrer"&gt;Full API here&lt;/a&gt;. &lt;/p&gt;
&lt;h3&gt;
  
  
  API
&lt;/h3&gt;

&lt;p&gt;Looking at the API we can see that at the bare minimum we need to pass as props are the following...&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;open: bool //If true, Snackbar is open.
message: string 
// To put snackbar at top center
anchorOrigin: { vertical: 'top', horizontal: 'center' }
onClose: function 
//Calls our onClose after time is up
autoHideDuration: number (ms) 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Because these props are the things that will customize any SnackBar/Alert it makes sense to set up our initial state (in our yet to be made reducer) as an object with the above key value pairs so we can easily spread the state object into the component. &lt;/p&gt;

&lt;h3&gt;
  
  
  Time to Code
&lt;/h3&gt;

&lt;p&gt;Similarly we will begin setting up the our redux code to handle this Alert system. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1) Types:&lt;/strong&gt; &lt;br&gt;
Simple enough, we have one to set/show a message and one to clear/hide a message.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;export const SHOW_ALERT = 'SHOW_ALERT';
export const CLEAR_ALERT = 'CLEAR_ALERT';
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;2) Action Creators:&lt;/strong&gt; &lt;br&gt;
showAlert returns an action object with a single key-value pair in its payload object; message.&lt;br&gt;
clearAlert just returns an action object with the type since we use our &lt;em&gt;INITIAL_STATE&lt;/em&gt; object in the reducer file to reset it back to normal&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;export const showAlert = (
    msgConfig = { message: 'default'}
) =&amp;gt; ({ type: SHOW_ALERT, payload: { ...msgConfig } });

export const clearAlert = () =&amp;gt; ({ type: CLEAR_ALERT });
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;3) Reducers:&lt;/strong&gt; &lt;br&gt;
Here's how we set up our INITIAL_STATE object with key-value pairs matching the props that will go into the Snackbar component.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const INITIAL_STATE = {
    open: false,
    message: '',
    anchorOrigin: { vertical: 'top', horizontal: 'center' },
    autoHideDuration: 3500
};
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the actual code handling SHOW_ALERT we just spread the previous state object (to keep all the other properties), set open to true and spread the action.payload into the object as well to get the message property.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const alertReducer = (state = INITIAL_STATE, action) =&amp;gt; {
    switch (action.type) {
        case SHOW_ALERT:
            /*
       action.payload looks like
        {message:''}
      */
            return { ...state, open: true, ...action.payload };
        case CLEAR_ALERT:
            return { ...INITIAL_STATE };
        default:
            return state;
    }
};
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;4) Components:&lt;/strong&gt; &lt;br&gt;
I will name this component Alert.js but in the returned JSX we will utilize the Snackbar component.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Note: Confusingly enough there is also a component in Material UI called Alert which we will not use&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { Snackbar, IconButton } from '@material-ui/core';
import CloseIcon from '@material-ui/icons/Close';
import { useDispatch, useSelector } from 'react-redux';
import { clearAlert } from '../actions/alertActions';

const Alert = () =&amp;gt; {
    const alert = useSelector((state) =&amp;gt; state.alert);
    const dispatch = useDispatch();
    const handleClose = () =&amp;gt; dispatch(clearAlert());
    return (
        &amp;lt;Snackbar
            {...alert}
            onClose={handleClose}
            action={
                    &amp;lt;IconButton
                        size='small'
                        aria-label='close'
                        color='inherit'
                        onClick={handleClose}
                    &amp;gt;
                        &amp;lt;CloseIcon fontSize='small' /&amp;gt;
                    &amp;lt;/IconButton&amp;gt;
            }
        /&amp;gt;
    );
};
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We use the useSelector hook to get the alert object out of state, we use useDispatch to grab the dispatch function then we spread all the properties from the alert object from state into the Snackbar. The action prop takes in some Components/JSX you can use to make the close button.  &lt;/p&gt;

&lt;h2&gt;
  
  
  Theming
&lt;/h2&gt;

&lt;p&gt;In addition to the makeStyles() hook we saw in part 2 Material UI also has a robust and customizable theme system that works by having a MuiThemeProvider component wrapped around your root component. Whatever created theme you passed in as a prop to that provider will be used whenever a makeStyles() hook is invoked&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/*
This theme variable is usually the
default Material UI theme but if
it detects a theme provider component
wrapped around it, that theme will instead be used
*/
const useStyles = makeStyles((theme) =&amp;gt; ({
    center: {
        etc...
                etc...
    },
}));
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;center&gt;![Theming detail page](https://i.gyazo.com/9873f614d8361456c669a8c7d5d1ad02.png) 
*How would we switch to dark mode?*
&lt;/center&gt;



&lt;p&gt;To create your own theme you need to leverage their API and use the createMuiTheme function. It takes in an object with key value pairs that can be set to colors (palette) font-sizes (via typography) and many more! &lt;/p&gt;

&lt;p&gt;(*&lt;em&gt;Note&lt;/em&gt;: I encourage everyone to look into the default theme object to see what can be set. It looks intimidating at first but it is just a &lt;a href="https://material-ui.com/customization/default-theme/#default-theme" rel="noopener noreferrer"&gt;giant object&lt;/a&gt;)&lt;/p&gt;

&lt;h3&gt;
  
  
  Dark Mode
&lt;/h3&gt;

&lt;p&gt;This is such a common use case they have a whole section in the documentation devoted to this! In this case we just need to create a new theme and set the value of palette.type to 'dark' or 'light'.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const darkTheme = createMuiTheme({
  palette: {
    type: 'dark',
  },
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;center&gt;   ![Dark mode differences](https://i.gyazo.com/e38ae2c672c6b841ae5b99fd52b8e20f.png) 
*By default only these properties are changed when the mode is switched*
&lt;/center&gt;



&lt;p&gt;Unfortunately this only modifies certain properties of the theme NOT including the primary or secondary colors. If you recall from article 2 we styled the button in our login component like so...&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const useStyles = makeStyles((theme) =&amp;gt; ({
    button: {
       etc...
       backgroundColor: theme.palette.primary.main,
         etc....
}));

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Thus switching the type to 'dark' will not affect theme.palette.primary so the button will remain the same color. If you wanted your component to be darkened as well we'll have to set our own palette.primary color when creating our theme!&lt;/p&gt;

&lt;h3&gt;
  
  
  Time to Code
&lt;/h3&gt;

&lt;p&gt;For the sake of simplicity I will only have 2 themes to switch between; light and dark.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1) Types&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;export const TOGGLE_THEME = 'TOGGLE_THEME';

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;2) Action Creators&lt;/strong&gt;&lt;br&gt;
That's it! The defined light and dark mode objects/themes are pre-defined in the themeReducer file&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;export const toggleTheme = () =&amp;gt; ({ type: TOGGLE_THEME });
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;3) Reducer&lt;/strong&gt;&lt;br&gt;
Since we are managing the theme object directly through redux our state will just be whatever object is the result of us calling the createMuiTheme() function. We create two themes for light and dark mode with the only difference being the primary.main color.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;let INITIAL_STATE = {};
const LIGHT_MODE_STATE = createMuiTheme({
    palette: {
        type: 'light',
        primary: {
            main: '#3f51b5', 
            contrastText: '#fff'
        }
    }
});
const DARK_MODE_STATE = createMuiTheme({
    palette: {
        type: 'dark',
        primary: {
            main: '#000',
            contrastText: '#fff'
        }
    }
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;*&lt;em&gt;Note: Any properties you don't set are inherited from the default theme so you can still use variables like typography, spacing etc... even though we didn't explicitly define it&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;We throw in a one-liner to detect the users theme preference from their computer via a function on the global window object.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;let matched = window.matchMedia('(prefers-color-scheme: dark)').matches;
matched
    ? (INITIAL_STATE = { ...DARK_MODE_STATE })
    : (INITIAL_STATE = { ...LIGHT_MODE_STATE });
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Finally we write the reducer itself; very simple, we just toggle from light to dark.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const themeReducer = (state = INITIAL_STATE, action) =&amp;gt; {
    switch (action.type) {
        case TOGGLE_THEME:
            //There is no payload we just replace the theme obj/state with the
            //opposite of whatever type is
            return state.palette.type === 'light'
                ? { ...DARK_MODE_STATE }
                : { ...LIGHT_MODE_STATE };
        default:
            return state;
    }
};
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;4) Provider and wrapping up&lt;/strong&gt;&lt;br&gt;
Okay we have a theme, we have a light and dark mode in our redux store, now what? Now we need to funnel that theme object into the MuiThemeProvider component Material UI gives us. When the theme changes in the store it will be updated here as well. We take in children as props (using destructuring) so anything wrapped in this Provider still shows up on the screen.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { MuiThemeProvider } from '@material-ui/core/styles';
import { useSelector } from 'react-redux';

function Theme({ children }) {
    const theme = useSelector((state) =&amp;gt; state.theme);
    return &amp;lt;MuiThemeProvider theme={theme}&amp;gt;{children}&amp;lt;/MuiThemeProvider&amp;gt;;
}

export default Theme;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now we can wrap the theme provider at our root component (App.js or something). Also note we added our Alert component here so it always shows up if we trigger it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { makeStyles } from '@material-ui/core/styles';
import { useSelector } from 'react-redux';
import Alert from './Alert';
import Login from './Login';
import Logout from './Logout';
import ThemeProvider from './ThemeProvider';
import CssBaseline from '@material-ui/core/CssBaseline';

function App() {
    const classes = useStyles();
    const auth = useSelector((state) =&amp;gt; state.auth);
    return (
        &amp;lt;ThemeProvider&amp;gt;
            &amp;lt;CssBaseline /&amp;gt;
            &amp;lt;main &amp;gt;
                &amp;lt;Alert /&amp;gt;
                {auth.loggedIn ? &amp;lt;Logout /&amp;gt; : &amp;lt;Login /&amp;gt;}
            &amp;lt;/main&amp;gt;
        &amp;lt;/ThemeProvider&amp;gt;
    );
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here we use a component called CSSBaseline also from Material UI (which they recommend to place at the root of your project) and it functions identically to &lt;a href="https://necolas.github.io/normalize.css/" rel="noopener noreferrer"&gt;Normalize CSS&lt;/a&gt; &lt;br&gt;
(Provides good defaults, consistent styling, box-sizing:border-box and most importantly allows our theme switch from light to dark to also change the body background )&lt;/p&gt;
&lt;h1&gt;
  
  
  Let's test the Alert!
&lt;/h1&gt;

&lt;p&gt;We setup both the Alert system and the theme system through redux but we never actually dispatched any actions to use them. For the theme we will make a switch in the next article, but you can switch between the "LIGHT_MODE_STATE" and "DARK_MODE_STATE" objects in the themeReducer to see how it would look. We want to see the alerts when a login succeeds, a login fails, a logout succeeds and a logout fails. All we have to do is dispatch our Alert action creator at the right time.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;//Inside Login.js and Logout.js
    const onSuccess = (res) =&amp;gt; {
        dispatch(googleOAuthLogin(res));
        dispatch(
            showAlert({
                message: 'Successfully logged in',
            })
        );
    };
    const onFailure = (res) =&amp;gt; {
        dispatch(googleOAuthLogin(res));
        dispatch(
            showAlert({
                message: 'Login failed ',
            })
        );
    };
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;iframe src="https://codesandbox.io/embed/nxxel"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;center&gt;*Yes, the button should do nothing until you plug in your client id from the first article* &lt;/center&gt;



&lt;p&gt;We're done setting up redux! In the last article we will make the mobile responsive navbar that displays the user's info when they're logged in and a we'll make a switch for dark mode!&lt;/p&gt;

</description>
      <category>redux</category>
      <category>react</category>
      <category>javascript</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Let's Make a Redux + Material UI + OAuth Starter template! Pt 2. Login/Logout</title>
      <dc:creator>Ethan Soo Hon</dc:creator>
      <pubDate>Sat, 20 Feb 2021 01:31:50 +0000</pubDate>
      <link>https://dev.to/ethanny2/let-s-make-a-redux-material-ui-oauth-starter-template-pt-2-login-logout-4lga</link>
      <guid>https://dev.to/ethanny2/let-s-make-a-redux-material-ui-oauth-starter-template-pt-2-login-logout-4lga</guid>
      <description>&lt;p&gt;In this part of the tutorial we will take the client ID we got in part 1 and hook it up to a Login and Logout component that will use the &lt;a href="https://www.npmjs.com/package/react-google-login"&gt;react-google-login library&lt;/a&gt;. Here's the packages you need&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;"dependencies": {
    "@material-ui/core": "^4.11.2",
    "@material-ui/icons": "^4.11.2",
    "@material-ui/lab": "^4.0.0-alpha.57",
    "@material-ui/styles": "^4.11.2",
    "react": "^17.0.1",
    "react-dom": "^17.0.1",
    "react-google-login": "^5.2.2",
    "react-redux": "^7.2.2",
    "react-scripts": "4.0.1",
    "redux": "^4.0.5"
  }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;(&lt;em&gt;Already assuming you have your CRA + redux setup&lt;/em&gt;)&lt;/p&gt;

&lt;p&gt;The documentation for react-google-login is very helpful and concise. The only thing I feel is missing are instructions to get your Google OAuth client id which I covered in the 1st article. &lt;br&gt;
Now we could use the built in components shipped with the library and supply them with specific props to look something like this...&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  &amp;lt;GoogleLogin
    clientId="zzzzz"
    buttonText="Login"
    onSuccess={responseGoogle} //Some function 
    onFailure={responseGoogle}
  /&amp;gt;
  //same for GoogleLogout component
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is serviceable but we eventually want to set up a theme for our project and have the styles of all our components switch when we go from light mode -&amp;gt; dark mode. So we will create our own Login and Logout button from Material UI components and use the &lt;em&gt;hooks useGoogleLogin() useGoogleLogout()&lt;/em&gt; also in this library to make our buttons.&lt;br&gt;&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--TlbcCwmF--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://i.gyazo.com/514388b99acc947a1520c9983a9b1a7f.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--TlbcCwmF--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://i.gyazo.com/514388b99acc947a1520c9983a9b1a7f.png" alt="useGoogleLogin"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;The props that went into the GoogleLogin component are now passed into this hook function as an object&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The useGoogleLogout() hook is pretty much identical in functionality so the most important part is now writing the onSuccess and onFailure functions for both. Let's check the docs to see what those functions should do&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--oT6BGJJW--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://i.gyazo.com/a79e40817ee65d36f6c6aabcd1ae5cb7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--oT6BGJJW--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://i.gyazo.com/a79e40817ee65d36f6c6aabcd1ae5cb7.png" alt="onSuccess callback"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--b6K1ZpzX--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://i.gyazo.com/5351522a9caef9746ab0dfb215eb88e0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--b6K1ZpzX--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://i.gyazo.com/5351522a9caef9746ab0dfb215eb88e0.png" alt="onFailure callback"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The expected object to be returned if the authentication succeeds is something with the tokenId, profileObj, googleId (etc...) properties. If that same request fails an object is sent to onFailure that includes an error property along with some details about the message.&lt;/p&gt;
&lt;h2&gt;
  
  
  Time to Code
&lt;/h2&gt;

&lt;p&gt;...With that we have everything we need to start coding! Since we will store user information in the redux store let's set up those pieces first&lt;/p&gt;

&lt;p&gt;Setting up your redux folders is highly opinionated but this is how I set up my folders&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;|- reducers
|- types
|- actions
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;1) Types:&lt;br&gt;
Fairly simple there are only 2 possible states; the user logging in and the user logging out&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;export const SIGN_IN = 'SIGN_IN';
export const SIGN_OUT = 'SIGN_OUT';
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;2) Action Creators:&lt;br&gt;
We'll write two functions that return action objects one for Login and one for Logout.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/*
  Will be passed in as the onSuccess and onFailure callback
  for useGoogleLogin() hook
/*
export const googleOAuthLogin = (response) =&amp;gt; {
    const action = { type: SIGN_IN };
    let payload;
    if (typeof response === 'undefined' || response.error) {
        //If login fails
        payload = null;
    } else {
        payload = response;
    }
    action.payload = payload;
    return action;
};
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For the logout we don't necessarily need to handle any errors (see we didn't even accept an argument here) because all we're really doing is just clearing the user out of the redux store.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/*
  Will be passed in as the onSuccess and onFailure callback
  for useGoogleLogout() hook
/*
export const googleOAuthLogout = () =&amp;gt; {
    const action = { type: SIGN_OUT };
    return action;
};
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;3) Reducer&lt;br&gt;
I chose to store this piece of state in the redux store under the "auth" key which has an initial state I defined to be...&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const INITIAL_STATE = {
    loggedIn: false,
    user: null
};
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We write the reducer handling both SIGN_IN and SIGN_OUT actions (don't forget to use default parameters!). For SIGN_IN our action.payload is null if it failed, but if it succeeded our Google response object should be in there.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;case SIGN_IN:
 let loggedIn = action.payload ? true : false;
 return loggedIn ?
 {...state,loggedIn,user: {                      
    tokenId: action.payload.tokenId,                     
    ...action.payload.profileObj
   }
 }
: { ...state, loggedIn, user: null };

/*
 If successful looks state looks like 
 {loggedIn: true, user: {tokenId: "sometoken" , profileObj: {}}
*/

case SIGN_OUT:
 return { ...INITIAL_STATE};
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;4) Login Component&lt;/p&gt;

&lt;p&gt;Without talking too much about the actual CSS used to make the buttons let's quickly examine how to use the built-in styling system for Material UI&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { makeStyles } from '@material-ui/core/styles';
const useStyles = makeStyles((theme) =&amp;gt; ({
    center: {
        display: 'flex',
        justifyContent: 'center'
    },
    button: {
        textTransform: 'none',
        marginTop: theme.spacing(10),
        display: 'flex',
        alignItems: 'center',
        boxShadow: theme.shadows[3],
        backgroundColor: theme.palette.primary.main,
        color: theme.palette.primary.contrastText,
        transition: 'background-color 0.5s',
        '&amp;amp;:hover': {
            backgroundColor: theme.palette.primary.dark,
            transition: 'background-color 0.5s',
            cursor: 'pointer'
        }
    },
}));
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We return an object from the makeStyles callback that has key value pairs where the &lt;em&gt;keys are class names&lt;/em&gt; you wish to use and the value is always an object that specifies CSS properties. (Keep in mind CSS properties are camelCased)&lt;/p&gt;

&lt;h3&gt;
  
  
  *What is the theme variable? *
&lt;/h3&gt;

&lt;p&gt;Since we don't have a theme defined yet Material UI supplies a default theme for us that you can see &lt;a href="https://material-ui.com/customization/default-theme/"&gt;here&lt;/a&gt; (its just a giant object)&lt;/p&gt;

&lt;p&gt;To use these classes we simply call the function above (we called it useStyles) and we get back our object.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const classes = useStyles();
return(
&amp;lt;p className={classes.center}&amp;gt; Hello! &amp;lt;/p&amp;gt;
)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I will be using the hooks provided by react-redux but this is equivalent to use mapStateToProps (replaced by useSelector) and mapDispatchToProps(replaced by useDipatch; we have to manually dispatch it)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;...
import googleLogo from '../images/google-logo.png';
import { useDispatch } from 'react-redux';
...


const clientId =
    'blahblahblahblah.apps.googleusercontent.com';
function Login() {
    const onSuccess = (res) =&amp;gt; {
        dispatch(googleOAuthLogin(res));
    };
    const onFailure = (res) =&amp;gt; {
        dispatch(googleOAuthLogin(res));
    };

    const { signIn } = useGoogleLogin({
        onSuccess,
        onFailure,
        clientId,
        isSignedIn: true
    });

    return (
        &amp;lt;Container component='section' className={classes.center}&amp;gt;
            &amp;lt;Button className={classes.button} onClick={signIn}&amp;gt;
                &amp;lt;Avatar src={googleLogo} className={classes.avatar} /&amp;gt;
                &amp;lt;Typography component='p' variant='h6' className={classes.text}&amp;gt;
                    Sign in with Google
                &amp;lt;/Typography&amp;gt;
            &amp;lt;/Button&amp;gt;
        &amp;lt;/Container&amp;gt;
    );
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;




&lt;center&gt; &lt;em&gt;We use clientId from article 1, and isSignedIn is a boolean used to persist the users login across sessions via a entry in localStorage&lt;/em&gt; &lt;/center&gt;
&lt;br&gt;
&lt;br&gt;

&lt;p&gt;To keep the styling consistent we use the same makeStyles object for the Logout component the only difference is the functions passed into useGoogleLogout are called onFailure and onLogoutSuccess.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
function Logout() {
    const classes = useStyles();
    const dispatch = useDispatch();
    const onSuccess = (res) =&amp;gt; {
        dispatch(googleOAuthLogout(res));
    };
    const onFailure = (res) =&amp;gt; {
        dispatch(googleOAuthLogout(res));
    };
    const { signOut } = useGoogleLogout({
        onFailure,
        onLogoutSuccess: onSuccess,
        clientId,
        isSignedIn: true
    });
    return (
        &amp;lt;Container component='section' className={classes.center}&amp;gt;
            &amp;lt;Button className={classes.button} onClick={signOut}&amp;gt;
                &amp;lt;Avatar src={googleLogo} className={classes.avatar} /&amp;gt;
                &amp;lt;Typography component='p' variant='h6' className={classes.text}&amp;gt;
                    Sign out of Google
                &amp;lt;/Typography&amp;gt;
            &amp;lt;/Button&amp;gt;
        &amp;lt;/Container&amp;gt;
    );
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Last Step!
&lt;/h1&gt;

&lt;p&gt;Lets go to App.js (or whatever your root component is called) and add conditional rendering for these components. We'll reach into the store with useSelector and check the auth.loggedIn property to determine what button to show.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function App() {
    const auth = useSelector((state) =&amp;gt; state.auth);
    return (
            &amp;lt;main&amp;gt;
                {auth.loggedIn ? &amp;lt;Logout /&amp;gt; : &amp;lt;Login /&amp;gt;}
            &amp;lt;/main&amp;gt;
        &amp;lt;/ThemeProvider&amp;gt;
    );
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Your project should look something like this now!&lt;/p&gt;

&lt;p&gt;&lt;iframe src="https://codesandbox.io/embed/ux7m8"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;Part 3 will set up the Alert system through redux and the theme system so we can easily switch from light to dark mode.&lt;/p&gt;

</description>
      <category>redux</category>
      <category>react</category>
      <category>oauth</category>
      <category>javascript</category>
    </item>
    <item>
      <title>Let's Make a Redux + Material UI + OAuth Starter template! Pt 1. What's OAuth??</title>
      <dc:creator>Ethan Soo Hon</dc:creator>
      <pubDate>Fri, 19 Feb 2021 03:24:54 +0000</pubDate>
      <link>https://dev.to/ethanny2/let-s-make-a-redux-material-ui-oauth-starter-template-pt-1-what-s-oauth-479j</link>
      <guid>https://dev.to/ethanny2/let-s-make-a-redux-material-ui-oauth-starter-template-pt-1-what-s-oauth-479j</guid>
      <description>&lt;p&gt;In this 4 part tutorial series we will set up a starting template using Material UI , Redux and Google OAuth 2.0. As seen in the cover image this template will help bootstrap front-end projects while taking care of some harder things to implement in the front-end world, namely...&lt;/p&gt;

&lt;p&gt;1) An alert/notification system setup through the Redux store&lt;br&gt;
2) An easily customizable theme system with the built in CSS-in-JS solutions offered by Material-UI&lt;br&gt;
3) Client-side OAuth and a mobile responsive navbar that is filled with the user's info when logged in  &lt;/p&gt;

&lt;p&gt;&lt;a href="https://redux-oauth.netlify.app/" rel="noopener noreferrer"&gt;Live example for those interested&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Prerequisites
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Familiarity with React hooks and Redux&lt;/li&gt;
&lt;li&gt;Have NPM/Node installed&lt;/li&gt;
&lt;li&gt;Know about the concept of a component library in React (it's okay if you've never used one!)&lt;/li&gt;
&lt;li&gt;Know about the concepts of CSS in JS (also okay if never used before)&lt;/li&gt;
&lt;li&gt;A Google Cloud Platform account (free) and an OAuth 2.0 Client ID (also free, may require gmail account)&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  What's OAuth?
&lt;/h3&gt;

&lt;p&gt;In the past years these buttons that allow you to sign in with some other social media account have become more and more prevalent on the web.&lt;br&gt;
As users we all know the advantages; less passwords to keep track of and a better sense of trust if you can log-in to an unfamiliar app with an already created account.&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/http%3A%2F%2Flipis.github.io%2Fbootstrap-social%2Fassets%2Fimg%2Fbootstrap-social.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/http%3A%2F%2Flipis.github.io%2Fbootstrap-social%2Fassets%2Fimg%2Fbootstrap-social.png" alt="OAuth Buttons"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;center&gt;*Seen these before?*&lt;/center&gt;



&lt;p&gt;As developers OAuth gives all the above advantages to your users PLUS the ability to easily use a users public information and associate a user with a Google (or Twitter etc...) account ID.&lt;/p&gt;

&lt;p&gt;Without getting too much into the weeds I think this &lt;a href="https://www.digitalocean.com/community/tutorials/an-introduction-to-oauth-2" rel="noopener noreferrer"&gt;Digital Ocean Post&lt;/a&gt; does a great job of explaining the concept&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fassets.digitalocean.com%2Farticles%2Foauth%2Fabstract_flow.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fassets.digitalocean.com%2Farticles%2Foauth%2Fabstract_flow.png" alt="OAuth Strategy"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;center&gt; 😵 &lt;/center&gt;



&lt;p&gt;It seems complex at first but much this process is abstracted away by the React library used here called &lt;a href="https://www.npmjs.com/package/react-google-login" rel="noopener noreferrer"&gt;react-google-login&lt;/a&gt;. It helps to visualize these steps in the context of the application so let's see how that looks...&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1)&lt;/strong&gt; Our App sends a request to user to ask for permission this is triggered when our button is clicked&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fc0o5xyaokqkeq7usgma5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fc0o5xyaokqkeq7usgma5.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;br&gt;
&lt;strong&gt;2)&lt;/strong&gt; The user logins in and grants permission&lt;br&gt;
&lt;strong&gt;3)&lt;/strong&gt; react-google-login (if step 2 succeeded) initiates step 3 and requests access for the users info from their servers&lt;br&gt;
&lt;strong&gt;4)&lt;/strong&gt; The token for OAuth access and some public user profile info is sent back to client side and stored in the redux store.&lt;/p&gt;

&lt;p&gt;In this template we never actually do anything with the token so 5 and 6 are left to be implemented later.&lt;/p&gt;

&lt;h2&gt;
  
  
  Getting Setup through Google Cloud Platform
&lt;/h2&gt;

&lt;p&gt;The first thing you need to have your web app communicate with Google's OAuth client is a Google Cloud Platform account, for this you need a free gmail account.&lt;/p&gt;

&lt;h3&gt;
  
  
  Steps
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Go to &lt;a href="https://console.cloud.google.com/" rel="noopener noreferrer"&gt;https://console.cloud.google.com/&lt;/a&gt; and sign up for an individual account. Yes, you need to enter a credit card for the free trial but the platform will never charge you after you used up your credit and additionally getting an OAuth client ID to use is also free
&lt;/li&gt;
&lt;li&gt;Once on the dashboard (if this is your first time) you should see in the navbar a "My First Project" tab. This is a default project started for you automatically; for simplicity's sake we'll use that.&lt;/li&gt;
&lt;li&gt;On the left side you should see a hamburger menu which once expanded you should see a "APIs and Services" tab, which has the sub-section called "Credentials"&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fi.gyazo.com%2F69aa5435f29fe96fb1af85bd962b6367.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fi.gyazo.com%2F69aa5435f29fe96fb1af85bd962b6367.png" alt="Dashboard credential screen"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;center&gt; *You should be here* &lt;/center&gt;



&lt;ul&gt;
&lt;li&gt;Afterwards we have to click "configure consent screen", select user type "External" and then click Create&lt;/li&gt;
&lt;li&gt;You will be taken to a form to fill with app information (your email, app name etc...). Fill out only the required fields and DON'T add any authorized domains, you can do this later when creating the clientID.&lt;/li&gt;
&lt;li&gt;Next we are taken to a scopes screen in which you have to configure what type of access you want from Google OAuth; &lt;/li&gt;
&lt;li&gt;Click "Add or Remove Scopes" while keeping in mind the default scope for react-google-login is as follows "profile email" and let's also add openid scope to get their Google ID.
&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fi.gyazo.com%2F5683dbb3cf16f1da8b690aec0fbb7a91.png" alt="Scopes screen"&gt;
&lt;center&gt; &lt;em&gt;Just a little further&lt;/em&gt; &lt;/center&gt;
&lt;/li&gt;
&lt;/ul&gt;



&lt;ul&gt;
&lt;li&gt;Next it will ask how many test users out of 100 you wish to register BUT we're going to leave that blank since you are only bound by this restriction while you have an OAuth client that requests sensitive scopes. We only request email, personal info and ID which are considered non-sensitive scopes so we don't have to worry about that. Your actual limit with this OAuth is 10,000 token grants per day.&lt;/li&gt;
&lt;li&gt;Finally go to save/continue now we can finally go back to the "API &amp;amp; Services" on Credentials.&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Near the top of the page click the "+ create credentials", select "OAuth Client Id", choose web application, name the app again (just used internally) and now we can add Authorized JavaScript origins. For now let's just make it so it works on &lt;a href="http://localhost:3000" rel="noopener noreferrer"&gt;http://localhost:3000&lt;/a&gt; and click create.&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fi.gyazo.com%2F2947f8aab15a4e2a5d8d2fe47c13faf6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fi.gyazo.com%2F2947f8aab15a4e2a5d8d2fe47c13faf6.png" alt="Scopes screen"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;center&gt; *Done!* &lt;/center&gt;


&lt;/li&gt;
&lt;li&gt;&lt;p&gt;A screen should pop up with both a client ID and a client Secret. The client secret is used server-side so we don't need it here but we will take the Client ID and copy it somewhere. &lt;br&gt;
&lt;em&gt;Note!&lt;/em&gt; : You don't need to hide your clientID in .env ! We restricted the URLs that can access it so it should be fine out in the open.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Next article we will make the &lt;em&gt;Login&lt;/em&gt; and &lt;em&gt;Logout&lt;/em&gt; components using your clientID, store the fetched user info in the redux store, and examine how the library persists the users logged in state through client-side storage!&lt;/p&gt;

</description>
      <category>react</category>
      <category>redux</category>
      <category>tutorial</category>
      <category>oauth</category>
    </item>
  </channel>
</rss>
