<?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: Josiah Ayres</title>
    <description>The latest articles on DEV Community by Josiah Ayres (@josiahayres).</description>
    <link>https://dev.to/josiahayres</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%2F712655%2F0776aea9-bf0a-486b-a86b-552c77e73fee.png</url>
      <title>DEV Community: Josiah Ayres</title>
      <link>https://dev.to/josiahayres</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/josiahayres"/>
    <language>en</language>
    <item>
      <title>Mantine Themes in Storybook 🤯</title>
      <dc:creator>Josiah Ayres</dc:creator>
      <pubDate>Sun, 10 Jul 2022 10:34:49 +0000</pubDate>
      <link>https://dev.to/josiahayres/mantine-themes-in-storybook-1e58</link>
      <guid>https://dev.to/josiahayres/mantine-themes-in-storybook-1e58</guid>
      <description>&lt;p&gt;Are you currently using &lt;a href="https://storybook.js.org"&gt;Storybook&lt;/a&gt; and &lt;a href="https://mantine.dev"&gt;Mantine&lt;/a&gt; component library to develop your React application?&lt;/p&gt;

&lt;p&gt;If so, my newly published storybook addon might make your life easier!&lt;/p&gt;

&lt;h3&gt;
  
  
  Key Features
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Easily have Storybook display your custom theme for all Stories.&lt;/li&gt;
&lt;li&gt;Switch between multiple custom themes (e.g. dark and light mode) directly from the Mantine Theme addon panel.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  See it in action
&lt;/h3&gt;

&lt;p&gt;This link will take you to the test Storybook, click on the &lt;em&gt;Mantine Theme&lt;/em&gt; addon to switch between two predefined themes &amp;amp; see the Mantine button reflect it.&lt;/p&gt;


&lt;div class="crayons-card c-embed text-styles text-styles--secondary"&gt;
    &lt;a href="https://josiahayres.github.io/storybook-addon-mantine/?path=/story/mantine-button--primary" rel="noopener noreferrer"&gt;
      josiahayres.github.io
    &lt;/a&gt;
&lt;/div&gt;


&lt;h3&gt;
  
  
  How to install
&lt;/h3&gt;

&lt;p&gt;You can get the &lt;a href="https://storybook.js.org/addons/storybook-addon-mantine"&gt;Storybook addon here&lt;/a&gt;.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;code&gt;npm i -D storybook-addon-mantine&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Register the addon &lt;code&gt;.storybook/main.js&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Provide your theme(s) to the addon &lt;code&gt;.storybook/preview.js&lt;/code&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://github.com/josiahayres/storybook-addon-mantine#register-the-addon"&gt;See full details on my GitHub page&lt;/a&gt;&lt;/p&gt;

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

&lt;p&gt;I'd like to be able to showcase the values of the currently selected theme, and eventually customise the theme directly from storybook. &lt;/p&gt;

&lt;p&gt;Would you use this functionality if it existed? Is it sufficient being able to configure the themes in the storybook preview file?&lt;/p&gt;

</description>
      <category>react</category>
      <category>storybook</category>
      <category>mantine</category>
      <category>themes</category>
    </item>
    <item>
      <title>Read this before using React 18...</title>
      <dc:creator>Josiah Ayres</dc:creator>
      <pubDate>Sat, 21 May 2022 02:07:53 +0000</pubDate>
      <link>https://dev.to/josiahayres/read-this-before-using-react-18-5971</link>
      <guid>https://dev.to/josiahayres/read-this-before-using-react-18-5971</guid>
      <description>&lt;p&gt;React 18 was released on 29 March 2022.&lt;/p&gt;

&lt;p&gt;After reading the &lt;a href="https://reactjs.org/blog/2022/03/08/react-18-upgrade-guide.html"&gt;How to Upgrade to React 18&lt;/a&gt; blog post these were my key takeaway points: &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Updates to Client Rendering APIs, one minor change to apply in your main &lt;code&gt;index.tsx&lt;/code&gt; file:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Before&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;render&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react-dom&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;container&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getElementById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;app&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;render&lt;/span&gt;&lt;span class="p"&gt;(&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;App&lt;/span&gt; &lt;span class="na"&gt;tab&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"home"&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;,&lt;/span&gt; &lt;span class="nx"&gt;container&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// After&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;createRoot&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react-dom/client&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;container&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getElementById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;app&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;root&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;createRoot&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;container&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// createRoot(container!) if you use TypeScript&lt;/span&gt;
&lt;span class="nx"&gt;root&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;render&lt;/span&gt;&lt;span class="p"&gt;(&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;App&lt;/span&gt; &lt;span class="na"&gt;tab&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"home"&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ol&gt;
&lt;li&gt;Updates to TypeScript definitions. Developers must now explicitly list the children prop when defining props, for example:
&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;MyButtonProps&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;children&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ReactNode&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;The blog post explains the other changes and additions to React 18, however most React developers won't need to do anything.&lt;/p&gt;

&lt;p&gt;This gave me confidence to jump right in to upgrading my application to React 18.&lt;/p&gt;
&lt;h2&gt;
  
  
  The Upgrade to 18
&lt;/h2&gt;

&lt;p&gt;Straight away I noticed some weird behaviours:&lt;/p&gt;

&lt;p&gt;&lt;iframe src="https://codesandbox.io/embed/react-18-upgrade-gotcha-kjrtdr"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;Jumping into the console, I could see that my component "setup" &lt;code&gt;useEffect&lt;/code&gt;, with an empty dependency array was being triggered twice.&lt;br&gt;
I was sure I hadn't changed the component code, and could not understand why I was seeing my component double rendering.&lt;/p&gt;


&lt;div class="crayons-card c-embed text-styles text-styles--secondary"&gt;
      &lt;div class="c-embed__cover"&gt;
        &lt;a href="https://giphy.com/gifs/CulturaJubile-fail-no-7E8UUn3jg36aDEWdBO" class="c-link s:max-w-50 align-middle" rel="noopener noreferrer"&gt;
          &lt;img alt="" src="https://res.cloudinary.com/practicaldev/image/fetch/s--qLFixJ03--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://media0.giphy.com/media/7E8UUn3jg36aDEWdBO/giphy.gif%3Fcid%3D790b7611439a4d3dcc01fc0d538670f4a55616053a15d9b2%26rid%3Dgiphy.gif%26ct%3Dg" height="360" class="m-0" width="480"&gt;
        &lt;/a&gt;
      &lt;/div&gt;
    &lt;div class="c-embed__body"&gt;
      &lt;h2 class="fs-xl lh-tight"&gt;
        &lt;a href="https://giphy.com/gifs/CulturaJubile-fail-no-7E8UUn3jg36aDEWdBO" rel="noopener noreferrer" class="c-link"&gt;
          Catastrophe No GIF by Cultura - Find &amp;amp; Share on GIPHY
        &lt;/a&gt;
      &lt;/h2&gt;
        &lt;p class="truncate-at-3"&gt;
          Discover &amp;amp; share this Cultura GIF with everyone you know. GIPHY is how you search, share, discover, and create GIFs.
        &lt;/p&gt;
      &lt;div class="color-secondary fs-s flex items-center"&gt;
          &lt;img alt="favicon" class="c-embed__favicon m-0 mr-2 radius-0" src="https://res.cloudinary.com/practicaldev/image/fetch/s--EnkhlOxW--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://giphy.com/static/img/favicon.png" width="16" height="16"&gt;
        giphy.com
      &lt;/div&gt;
    &lt;/div&gt;
&lt;/div&gt;



&lt;p&gt;A quick Google search pointed to the &lt;code&gt;&amp;lt;StrictMode /&amp;gt;&lt;/code&gt; component being the cause. &lt;/p&gt;

&lt;h2&gt;
  
  
  The (interim) fix
&lt;/h2&gt;

&lt;p&gt;Changing my code from&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;StrictMode&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;ReactDOMClient&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;react-dom/client&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;App&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./App&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;rootElement&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getElementById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;root&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;root&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;ReactDOMClient&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;createRoot&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;rootElement&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nx"&gt;root&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;render&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;StrictMode&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;App&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;StrictMode&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;to&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;ReactDOMClient&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;react-dom/client&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;App&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./App&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;rootElement&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getElementById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;root&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;root&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;ReactDOMClient&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;createRoot&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;rootElement&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nx"&gt;root&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;render&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;App&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;seemed to fix all the issues and double rendering of setup functions.&lt;/p&gt;

&lt;h2&gt;
  
  
  The cause
&lt;/h2&gt;

&lt;p&gt;From the bottom end of the &lt;a href="https://reactjs.org/blog/2022/03/08/react-18-upgrade-guide.html#updates-to-strict-mode"&gt;React 18 Upgrade Guide post&lt;/a&gt; they explain: &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;To demonstrate the development behavior you’ll see in Strict Mode with this feature, consider what happens when React mounts a new component. Without this change, when a component mounts, React creates the effects:&lt;/p&gt;


&lt;pre class="highlight plaintext"&gt;&lt;code&gt;* React mounts the component.
  * Layout effects are created.
  * Effects are created.
&lt;/code&gt;&lt;/pre&gt;


&lt;p&gt;With Strict Mode starting in React 18, whenever a component mounts in development, React will simulate immediately unmounting and remounting the component:&lt;/p&gt;


&lt;pre class="highlight plaintext"&gt;&lt;code&gt;* React mounts the component.
    * Layout effects are created.
    * Effect effects are created.
* React simulates effects being destroyed on a mounted component.
    * Layout effects are destroyed.
    * Effects are destroyed.
* React simulates effects being re-created on a mounted component.
    * Layout effects are created
    * Effect setup code runs
&lt;/code&gt;&lt;/pre&gt;


&lt;p&gt;On the second mount, React will restore the state from the first mount. This feature simulates user behavior such as a user tabbing away from a screen and back, ensuring that code will properly handle state restoration.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  The proper fix
&lt;/h2&gt;

&lt;p&gt;Adding in a return statement to the useEffect to handle the cleanup of the effect on unmount.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;useEffect&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;useState&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;intervalInMs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;minuteInMs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;React18SafeTimer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;timeInSeconds&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setTime&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;updateTimerInterval&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setUpdateTimerInterval&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="nx"&gt;useEffect&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;React 18 Timer Setup&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;timerInterval&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;setInterval&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;setTime&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;t&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;t&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;intervalInMs&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="nx"&gt;minuteInMs&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
      &lt;span class="nx"&gt;intervalInMs&lt;/span&gt;
    &lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;setUpdateTimerInterval&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;timerInterval&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="c1"&gt;// THE FIX: Add next line to properly clean up useEffect&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;clearInterval&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;timerInterval&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;[]);&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;handleClearTimer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;clearInterval&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;updateTimerInterval&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;seconds since page load: &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;timeInSeconds&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;toFixed&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt; &lt;span class="na"&gt;onClick&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;handleClearTimer&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Stop Timer&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://reactjs.org/docs/hooks-reference.html#cleaning-up-an-effect"&gt;See more at the Hooks API Reference page&lt;/a&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;If you're having issues after upgrading to React 18, take a look at any of the following, as StrictMode changes around unmounting and remounting changes includes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;componentDidMount&lt;/li&gt;
&lt;li&gt;componentWillUnmount&lt;/li&gt;
&lt;li&gt;useEffect&lt;/li&gt;
&lt;li&gt;useLayoutEffect&lt;/li&gt;
&lt;li&gt;useInsertionEffect&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://reactjs.org/docs/strict-mode.html#ensuring-reusable-state"&gt;See this page for more details&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Why should I use StrictMode?
&lt;/h2&gt;

&lt;p&gt;StrictMode is a (development mode) tool for highlighting potential problems in an application. It does not run in Production environment. Like Fragment, StrictMode does not render any visible UI. It activates additional checks and warnings for its descendants.&lt;/p&gt;

&lt;p&gt;StrictMode currently helps with:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Identifying components with unsafe lifecycles&lt;/li&gt;
&lt;li&gt;Warning about legacy string ref API usage&lt;/li&gt;
&lt;li&gt;Warning about deprecated findDOMNode usage&lt;/li&gt;
&lt;li&gt;Detecting unexpected side effects&lt;/li&gt;
&lt;li&gt;Detecting legacy context API&lt;/li&gt;
&lt;li&gt;Ensuring reusable state&lt;/li&gt;
&lt;li&gt;Additional functionality will be added with future releases of React.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Why has React made these changes?
&lt;/h2&gt;

&lt;p&gt;In the future, we’d like to add a feature that allows React to add and remove sections of the UI while preserving state. For example, when a user tabs away from a screen and back, React should be able to immediately show the previous screen. To do this, React support remounting trees using the same component state used before unmounting.&lt;/p&gt;

&lt;p&gt;This feature will give React better performance out-of-the-box, but requires components to be resilient to effects being mounted and destroyed multiple times. Most effects will work without any changes, but some effects do not properly clean up subscriptions in the destroy callback, or implicitly assume they are only mounted or destroyed once.&lt;/p&gt;

&lt;p&gt;To help surface these issues, React 18 introduces a new development-only check to Strict Mode. This new check will automatically unmount and remount every component, whenever a component mounts for the first time, restoring the previous state on the second mount.&lt;/p&gt;

&lt;p&gt;Additional discussions on GitHub that gave a lot more context into the "why" behind the changes to StrictMode:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/reactwg/react-18/discussions/19"&gt;Adding Reusable State to StrictMode&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/reactwg/react-18/discussions/18"&gt;How to support Reusable State in Effects&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;p&gt;React 18 introduces changes which can lead to an unexpected Developer experience and messier console logs with same messages being triggered twice. It also introduces different application behaviour when running in development mode vs production, which is arguably undesirable.&lt;/p&gt;

&lt;p&gt;While these changes have been done for a good reason, and should be embraced rather than ignored, React devs need to know what to expect before upgrading. Hopefully this guide helps save you time and answers your questions. &lt;/p&gt;

</description>
      <category>tutorial</category>
      <category>javascript</category>
      <category>react</category>
    </item>
    <item>
      <title>Create a Python Layer for your AWS Lambda Function</title>
      <dc:creator>Josiah Ayres</dc:creator>
      <pubDate>Mon, 06 Dec 2021 23:51:18 +0000</pubDate>
      <link>https://dev.to/josiahayres/create-a-python-layer-for-your-aws-lambda-function-54j7</link>
      <guid>https://dev.to/josiahayres/create-a-python-layer-for-your-aws-lambda-function-54j7</guid>
      <description>&lt;h2&gt;
  
  
  Background
&lt;/h2&gt;

&lt;p&gt;I just finished creating a few small lambda functions using Python.&lt;br&gt;
Layers are a great way to manage application dependencies, and speeding up your deployment times.&lt;/p&gt;

&lt;p&gt;My project needed the following libraries:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://docs.python-requests.org/en/latest/" rel="noopener noreferrer"&gt;&lt;code&gt;requests&lt;/code&gt;&lt;/a&gt; for making HTTP requests.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://pysftp.readthedocs.io/en/release_0.2.9/" rel="noopener noreferrer"&gt;&lt;code&gt;pysftp&lt;/code&gt;&lt;/a&gt; for creating SSH connections to different servers. &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you need a different library, the approach should be the same, assuming it's installable using &lt;code&gt;pip&lt;/code&gt; or &lt;code&gt;pip3&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;Unfortunately we didn’t have access to &lt;a href="https://aws.amazon.com/ecr/" rel="noopener noreferrer"&gt;Container Registry (ECR)&lt;/a&gt; so we couldn't &lt;a href="https://docs.aws.amazon.com/lambda/latest/dg/images-create.html" rel="noopener noreferrer"&gt;create a docker container&lt;/a&gt;, which would have allowed us to install the dependencies as part of the docker container creation.&lt;/p&gt;

&lt;p&gt;We instead had to create &amp;amp; upload a zip file containing our application code and dependencies.&lt;/p&gt;

&lt;p&gt;While we could include the application dependencies in the zip we upload, this has a few disadvantages:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;It slows down each upload, which is not ideal as you might end up uploading a number of times. &lt;/li&gt;
&lt;li&gt;Your application code will not be viewable in the lambda console if your zip file ends up too large.&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;
  
  
  Creating a AWS Lambda layer
&lt;/h2&gt;
&lt;h3&gt;
  
  
  Application Setup
&lt;/h3&gt;

&lt;p&gt;So now we know why layers might be needed in your lambda function, let's look at how to create one.&lt;/p&gt;

&lt;p&gt;The sample project is also available on &lt;a href="https://github.com/josiahayres/aws-lambda-test-function" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Folder structure of a lambda layer:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/requirements.txt
/python/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Where &lt;code&gt;requirements.txt&lt;/code&gt; is a file with the names of the packages we’re using, and &lt;code&gt;python&lt;/code&gt; is an empty folder which we will be installing dependencies into. See the &lt;a href="https://docs.aws.amazon.com/lambda/latest/dg/configuration-layers.html" rel="noopener noreferrer"&gt;Lambda layer documentation&lt;/a&gt; for more information on why we need to install into the python folder.  &lt;/p&gt;

&lt;p&gt;My application folder on my computer looks something like this then:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/lambda_function.py
/lambda_layer/requirements.txt
/lambda_layer/python/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Setup Ubuntu VM
&lt;/h3&gt;

&lt;p&gt;AWS Lambda runs in a Linux machine, so you'll need to install the layer dependencies using an Linux OS. You can't directly follow these steps in MacOS or Windows.&lt;/p&gt;

&lt;p&gt;I won't cover how to create a Linux VM, as there are many good tutorials available with a quick search online.&lt;/p&gt;

&lt;h3&gt;
  
  
  Create the layer ZIP file
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;Remember, you need to run these commands in a Linux machine.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Navigate into the layer folder:&lt;br&gt;
&lt;code&gt;cd lambda_layer&lt;/code&gt; &lt;/p&gt;

&lt;p&gt;Install the dependencies into the python folder:&lt;br&gt;
&lt;code&gt;pip install -r requirements.txt -t .python&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Create the lambda layer zip:&lt;br&gt;
&lt;code&gt;zip -r ../app-name-depts-layer.zip *&lt;/code&gt; &lt;/p&gt;

&lt;p&gt;We now have a ZIP file (&lt;code&gt;app-name-depts-layer.zip&lt;/code&gt;) which can be uploaded to AWS as a Layer. This zip file should have a python folder inside it, with the application dependencies installed from &lt;code&gt;pip&lt;/code&gt; inside.&lt;/p&gt;
&lt;h2&gt;
  
  
  Create the layer in AWS
&lt;/h2&gt;

&lt;p&gt;Navigate to your AWS instance, and open Lambda function. Click the create layer button:&lt;br&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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frxboyif8rtwkmcy5n0cm.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%2Frxboyif8rtwkmcy5n0cm.png" alt="AWS Lambda create layer step 1"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Fill in the details of your layer:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;I recommend including the names of the packages that are included in the layer, as part of the description. This will be useful in the future, especially if you end up creating and using multiple layers.&lt;/p&gt;
&lt;/blockquote&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%2F1uhaetulsxvo64ppo0hb.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%2F1uhaetulsxvo64ppo0hb.png" alt="AWS Lambda create layer step 2"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Click &lt;em&gt;Create layer&lt;/em&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Configure Lambda function to use Layer.
&lt;/h2&gt;

&lt;p&gt;In your lambda function, scroll down to the bottom of the page, to the Layers section: &lt;/p&gt;

&lt;p&gt;Click on the &lt;em&gt;Add a layer&lt;/em&gt; button&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%2F85h5tltm0qvik3a9lbse.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%2F85h5tltm0qvik3a9lbse.png" alt="Add a layer to AWS Lambda function, step 1"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Select &lt;em&gt;Custom layers&lt;/em&gt;, then select the layer you just created, picking the latest version:&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%2Fdtn4hxk80ksnx6yet3wx.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%2Fdtn4hxk80ksnx6yet3wx.png" alt="Adding a layer to an AWS function"&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;Wait for the function to update:&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%2Fqrgmwii4o7nmnwdbtr4y.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%2Fqrgmwii4o7nmnwdbtr4y.png" alt="AWS Lambda function updated after adding layer"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;That’s it! &lt;/p&gt;
&lt;h2&gt;
  
  
  Test it out
&lt;/h2&gt;

&lt;p&gt;Now in your application code, you can simply import the packages installed in the layer. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;code&gt;lambda_function.py&lt;/code&gt;&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;import requests

def lambda_handler(event, context):
    test_url = 'https://jsonplaceholder.typicode.com/todos/1'
    response = requests.get(test_url)

    return {
        'statusCode': response.status_code,
        'body': response.json()
    }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the console it should look like this:&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%2Fzxfv0996jqqnsfzs2u2v.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%2Fzxfv0996jqqnsfzs2u2v.png" alt="Screenshot of AWS console - showing test Lambda function"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Testing this code should return: &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%2F8jipadodw1yh9h0e126l.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%2F8jipadodw1yh9h0e126l.png" alt="Result of test using application dependency from layer"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You now have the ability to make HTTP requests and can easily reuse the layer in different applications.&lt;/p&gt;

&lt;p&gt;Hopefully this helps get you started, you can easily extend this out as needed...&lt;/p&gt;

</description>
      <category>aws</category>
      <category>python</category>
      <category>serverless</category>
      <category>tutorial</category>
    </item>
  </channel>
</rss>
