<?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>Forem: RobbieGM</title>
    <description>The latest articles on Forem by RobbieGM (@robbiegm).</description>
    <link>https://forem.com/robbiegm</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%2F104485%2F126bf8ae-1dc9-4126-b48d-c334943b0e9e.png</url>
      <title>Forem: RobbieGM</title>
      <link>https://forem.com/robbiegm</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/robbiegm"/>
    <language>en</language>
    <item>
      <title>What does the frontend dev world need to make better applications?</title>
      <dc:creator>RobbieGM</dc:creator>
      <pubDate>Thu, 28 Jul 2022 21:47:01 +0000</pubDate>
      <link>https://forem.com/robbiegm/what-does-the-frontend-dev-world-need-to-make-better-applications-3ki2</link>
      <guid>https://forem.com/robbiegm/what-does-the-frontend-dev-world-need-to-make-better-applications-3ki2</guid>
      <description>&lt;p&gt;I finished a side project web app recently and am about to come upon a chunk of free time before uni starts again. It struck me how difficult it was to do things like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Make an animation performant (lots of CSS properties trigger paint or layout unexpectedly)&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Make components with good keyboard accessibility (not just tabbing), common mobile gesture support, etc.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Do styling properly (CSS modules aren't quite cutting it, and on the perf side sometimes recalculating styles takes up to 50ms!)&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I'd particularly like to improve the performance story in the frontend world but I'd be interested in creating or contributing to anything (build tools, libraries, linters, etc.) that makes it easier for devs to make a nice user experience. I was going to experiment a bit myself with things like shadow DOM, wasm, and web workers to see if those things might be suitable for the mainstream web (for wasm we have yew, for example, but it's niche). I thought that first, I should get the opinion of web devs more experienced than myself.&lt;/p&gt;

&lt;p&gt;To repeat the title question: What does the frontend dev world need to make better applications?&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>discuss</category>
    </item>
    <item>
      <title>16 Underused Web Platform Features</title>
      <dc:creator>RobbieGM</dc:creator>
      <pubDate>Fri, 14 Aug 2020 00:56:22 +0000</pubDate>
      <link>https://forem.com/robbiegm/16-underused-web-platform-features-3k90</link>
      <guid>https://forem.com/robbiegm/16-underused-web-platform-features-3k90</guid>
      <description>&lt;p&gt;What follows is a list of APIs and features that are uncommon to see in the wild, but have use cases nonetheless and the potential to greatly improve the experience your users have while visiting your website. Each feature below has a link to a demo so you can try it out in your browser. Without further ado...&lt;/p&gt;

&lt;p&gt;&lt;a href="https://web.dev/app-shortcuts/"&gt;&lt;strong&gt;App shortcuts&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This feature allows your PWA, when installed on the home screen, to show shortcut options when the app icon is long-pressed by the user. It is often used by messaging apps to provide shortcuts to frequently messaged users, though dynamically updating the shortcuts in your app manifest for a use case like that is &lt;a href="https://stackoverflow.com/questions/47762022/apply-changes-to-web-app-manifest-on-an-installed-pwa"&gt;not easy&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://web-share.glitch.me/"&gt;&lt;strong&gt;Web Share API&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Alright, this one is more well known but I feel like it is important enough that it should be included anyway. This API allows web apps on mobile devices to use the native share dialog.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://gauntface.github.io/simple-push-demo/"&gt;&lt;strong&gt;Web Push API&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is different from the notifications API. It's used to send notifications, but the important addition here is that the website does not need to be open in the browser in order for notifications to come through.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://whatwebcando.today/credentials.html"&gt;&lt;strong&gt;Credentials Management API&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This API allows web applications to store and retrieve credentials such as username/password pairs or federated login data. This could be used to provide a quick way to use saved logins without visiting a login page and clicking the log in button with autofilled credentials.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://web.dev/web-otp/"&gt;&lt;strong&gt;Web OTP API&lt;/strong&gt; (aka SMS Receiver API)&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The Web OTP API provides a simple way to use SMS for two-factor authentication. It lets the web application intercept certain text messages (ones which contain its origin) and use them to authorize the user if given permission. Definitely simpler for the user than having to type in a code!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://web.dev/content-visibility/"&gt;&lt;strong&gt;&lt;code&gt;content-visibility&lt;/code&gt; CSS Property&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;content-visibility&lt;/code&gt; property allows browser engines to render content much quicker by only rendering what is above the fold and waiting to render other content. This property has three possible values:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;visible&lt;/code&gt; - no effect&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;hidden&lt;/code&gt; - similar to &lt;code&gt;display: none&lt;/code&gt; but the browser does not discard the previous rendering state, so changing from &lt;code&gt;content-visibility: hidden&lt;/code&gt; to &lt;code&gt;visible&lt;/code&gt; is more performant than changing from &lt;code&gt;display: none&lt;/code&gt; to &lt;code&gt;block&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;auto&lt;/code&gt; - turns on "containment" - a way for the browser to estimate the size of an element in various ways without rendering descendants (for performance).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;More information is available in the link above or in &lt;a href="https://drafts.csswg.org/css-contain-2/#content-visibility"&gt;the spec&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://x9011.csb.app/"&gt;&lt;strong&gt;Keyboard Lock API&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Allows web apps in fullscreen mode, such as games or remote desktop applications, to listen to the activation of certain key combinations which would otherwise be trapped by the browser or OS (such as &lt;code&gt;Alt&lt;/code&gt; + &lt;code&gt;Tab&lt;/code&gt; or &lt;code&gt;Ctrl&lt;/code&gt; + &lt;code&gt;W&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;&lt;a href="https://googlechromelabs.github.io/text-editor/"&gt;&lt;strong&gt;Native Filesystem API&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Provides a way for web apps to open files and save them directly to the user's file system. This kind of thing is very useful for file editors. If you want to try the demo above, make sure to use Chrome and enable the experimental web platform feature &lt;a href="https://dev.tochrome://flags/#native-file-system-api"&gt;chrome://flags/#native-file-system-api&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://wake-lock-demo.glitch.me/"&gt;&lt;strong&gt;Wake Lock API&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Wish the screen wouldn't go to sleep while your web app is being used, even if not actively in a way which would normally keep the screen on? The Wake Lock API can be used to keep the user's device from going to sleep while they are, say, reading a recipe. This API helped &lt;a href="https://web.dev/betty-crocker/"&gt;Betty Crocker achieve a 300% increase in purchase intent indicators&lt;/a&gt; on their website.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Periodic Background Sync API&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Sorry I couldn't find a demo for this one. The background sync API is similar to the Push API in that it requires a service worker and receives information in the background. The app will periodically receive a &lt;code&gt;periodicsync&lt;/code&gt; event on the service worker which allows it an opportunity to fetch data. This API is most useful when you want to save content for offline use, but could be used to keep content cached and fresh so it is loaded instantly when the site is opened. More information can be found on the &lt;a href="https://web.dev/periodic-background-sync/"&gt;web.dev blog post about this feature&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://web-share.glitch.me"&gt;&lt;strong&gt;Web Share Target API&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The flip side of the Web Share coin is that not only can you share content to other apps, your app can be a target to receive shared content. First, however, the PWA must be installed. The demo above, as well as the API itself, only work in Chrome for Android at the time of this writing.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://contact-picker.glitch.me/"&gt;&lt;strong&gt;Contact Picker API&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This API lets users select contacts to upload to a website through a contact picker widget. Names, emails, telephone numbers, addresses, and icons can all be requested.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://mathiasbynens.be/demo/image-loading-lazy"&gt;&lt;strong&gt;Image lazy loading&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;loading&lt;/code&gt; attribute on an HTML &lt;code&gt;img&lt;/code&gt; element, when set to &lt;code&gt;"lazy"&lt;/code&gt;, instructs the browser not to load the image until it is in view or about to be scrolled into view. This results in bandwidth savings for users.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://paymentrequest.show/demo/"&gt;&lt;strong&gt;Payment Request API&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The payment request API is undoubtedly the most streamlined method to integrate payments into your website. It can show the user what they are buying, show how much it will cost, and even ask for shipping information. The user can pay with their saved credit card information or third party payment processor.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://badging-api.glitch.me/"&gt;&lt;strong&gt;App Badging API&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As a less intrusive (and permissionless) alternative to showing notifications is app badging. This API allows your app to set a badge number, such as a number of new unread notifications, on its icon.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://googlechrome.github.io/samples/vibration/"&gt;&lt;strong&gt;Vibration API&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Activates vibration hardware in the user's device, but must be in response to a click. (Vibration for notifications can be done through the notifications API.) Use sparingly--vibration is often more annoying than helpful, which may explain the API's absence in iOS Safari.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>javascript</category>
    </item>
    <item>
      <title>How to reload a Next.js page's initial props without reloading the whole page</title>
      <dc:creator>RobbieGM</dc:creator>
      <pubDate>Mon, 18 May 2020 14:08:25 +0000</pubDate>
      <link>https://forem.com/robbiegm/how-to-reload-a-next-js-page-s-initial-props-without-reloading-the-whole-page-3oid</link>
      <guid>https://forem.com/robbiegm/how-to-reload-a-next-js-page-s-initial-props-without-reloading-the-whole-page-3oid</guid>
      <description>&lt;p&gt;If you have made a Next.js page that loads data in its &lt;code&gt;getInitialProps&lt;/code&gt; function, you may have wanted to reload it in order to fetch the newest data after making some mutating API call. Hard-reloading the page will reset the user's scroll position and take extra time, so clearly that is not the best solution. You could also make some &lt;code&gt;fetchData&lt;/code&gt; function that gets called in getInitialProps, passes its data into the default value of a useState hook, and then gets updated by calling &lt;code&gt;fetchData&lt;/code&gt; again followed by setting the state. But wouldn't it be convenient if you could just have a function that reloaded your initial props?&lt;br&gt;
I made a higher order component to wrap Next.js pages that does exactly this. Here it is in TypeScript:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight typescript"&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;NextPage&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;NextPageContext&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;next&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;React&lt;/span&gt;&lt;span class="p"&gt;,&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="nx"&gt;PropsWithChildren&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;ComponentType&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&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;SoftReloadProps&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="cm"&gt;/**
   * Reloads the page's initialProps without causing a real browser "hard" reload.
   */&lt;/span&gt;
  &lt;span class="nx"&gt;softReload&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;OmitSoftReloadProps&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;Omit&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;keyof&lt;/span&gt; &lt;span class="nx"&gt;SoftReloadProps&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;type&lt;/span&gt; &lt;span class="nx"&gt;SoftReloadablePageInitialProps&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;TProps&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;OmitSoftReloadProps&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;TProps&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;context&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;NextPageContext&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="nx"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;NextPageWithInitialProps&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;P&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;IP&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;P&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;NextPage&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;P&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;IP&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;Required&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Pick&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;NextPage&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;P&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;IP&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;getInitialProps&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="cm"&gt;/**
 * Removes never-used context values to reduce bloat. Context values may come from server but then
 * be used client-side because they are saved in initial props.
 */&lt;/span&gt;
&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;minifyContext&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;context&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;NextPageContext&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nx"&gt;NextPageContext&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;...&lt;/span&gt;&lt;span class="nx"&gt;context&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;req&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;undefined&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;res&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;undefined&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;withSoftReload&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;TProps&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nx"&gt;SoftReloadProps&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;Page&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;NextPageWithInitialProps&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;TProps&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;OmitSoftReloadProps&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;TProps&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nx"&gt;NextPage&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;SoftReloadablePageInitialProps&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;TProps&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;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="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;getInitialProps&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="na"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;NextPageContext&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;SoftReloadablePageInitialProps&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;TProps&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;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="na"&gt;context&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;minifyContext&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="p"&gt;...(&lt;/span&gt;&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;Page&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getInitialProps&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;ctx&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;omitContextFromProps&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="nx"&gt;context&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;
  &lt;span class="p"&gt;}:&lt;/span&gt; &lt;span class="nx"&gt;SoftReloadablePageInitialProps&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;TProps&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;OmitSoftReloadProps&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;TProps&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;props&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;any&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="na"&gt;NewPage&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;NextPageWithInitialProps&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;SoftReloadablePageInitialProps&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;TProps&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;props&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// set inner page initial props to wrapper initial props minus context&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;initialProps&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setInitialProps&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="nx"&gt;omitContextFromProps&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
    &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;softReload&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;setInitialProps&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;children&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;...(&lt;/span&gt;&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;Page&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getInitialProps&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;context&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="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Page&lt;/span&gt;
        &lt;span class="p"&gt;{...(({&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;initialProps&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;softReload&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;Omit&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;TProps&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;keyof&lt;/span&gt; &lt;span class="nx"&gt;SoftReloadProps&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;SoftReloadProps&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;TProps&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt;
      &lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;    &lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;
  &lt;span class="nx"&gt;NewPage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getInitialProps&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;getInitialProps&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nx"&gt;NewPage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;displayName&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`withSoftReload(&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;Page&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;displayName&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;)`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;NewPage&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;withSoftReload&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;You can use this HOC like this in your pages:&lt;br&gt;
&lt;/p&gt;

&lt;div class="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;InitialProps&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;string&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;MyPage&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;NextPageWithInitialProps&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;InitialProps&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;SoftReloadProps&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;InitialProps&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;softReload&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="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&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;data&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;button&lt;/span&gt; &lt;span class="nx"&gt;onClick&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;softReload&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;Refresh&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/button&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;  &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nx"&gt;MyPage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getInitialProps&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;ctx&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="c1"&gt;// fetch data&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;withSoftReload&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;MyPage&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

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



&lt;p&gt;Hope you enjoy!&lt;/p&gt;

</description>
      <category>react</category>
      <category>nextjs</category>
      <category>javascript</category>
      <category>typescript</category>
    </item>
    <item>
      <title>Design Principles of Crank.js and React</title>
      <dc:creator>RobbieGM</dc:creator>
      <pubDate>Thu, 07 May 2020 16:43:12 +0000</pubDate>
      <link>https://forem.com/robbiegm/design-principles-of-crank-js-and-react-2e6k</link>
      <guid>https://forem.com/robbiegm/design-principles-of-crank-js-and-react-2e6k</guid>
      <description>&lt;p&gt;On April 15, 2020, a new frontend JavaScript framework was released. Yes, I know. I can already hear the groans of developers who have had to learn PHP, then Angular, then React, and now worry that they may have to learn this. The author of the framework &lt;a href="https://crank.js.org/blog/introducing-crank"&gt;apologized for the release&lt;/a&gt;, but thought that his framework would meaningfully impact the way that user interfaces are made in a way that benefits developers and users. In his article he explains the need for Crank.js and how he thinks React’s features are becoming more and more hacky and arcane. One example of this is React’s somewhat recent hooks API. While many React fans hail the release of hooks as the greatest feature of the framework, the author of Crank.js did not agree, describing his distaste for the “strangeness and pitfalls” of the hooks API. Anyone who has used React’s functional components with hooks will be familiar with how everything must be memoized to avoid unnecessary re-renders, requiring dependencies of functions to also be memoized, and so on and so forth until your every function is wrapped with useCallback and every variable with useMemo. The creator of the new framework also seemed less than enthusiastic about the upcoming release of React’s Suspense API, which is designed to avoid data-fetching waterfalls. Suspense detects that components need to load by having those components throwing promises during render time (yes, with the throw keyword as if throwing an error) which understandably seems weird. He complains that “it doesn’t even matter what the thrown promise fulfills to; instead, it’s an elaborate way to notify React that your components are ready to try and render again.” Furthermore, a cache must be maintained in order to avoid fetching the same data again and again on each re-render. In order to cache async calls, you must be able to uniquely key each one and know when to invalidate its results. The author expresses his disinterest for having to manage cache invalidation, and references the well-known joke that cache invalidation is one of the hardest problems in computer science. He eventually felt alienated by where React was going. He envisioned a world in which asynchrony was managed by JavaScript alone instead of by strange framework hacks. Why can’t components just return promises instead of JSX when they’re not done loading yet?&lt;/p&gt;

&lt;p&gt;In Crank.js, they can. Components can be plain functions, async functions, generators, and async generators. When a component needs to wait to render, it can simply return a promise instead of JSX. To add state to a component, you can simply add local variables and make the function a generator that yields JSX infinitely. The library also allows you to dispatch and handle custom events, similar to Vue.js. While the Crank framework makes use of numerous design principles shared by nearly all frontend frameworks, such as lifting state up and using composition over inheritance, it eschews the notion that all renders must be pure and side-effect free, a core principle of React’s design that the author of Crank.js describes as “dogmatic” and impractical.&lt;/p&gt;

&lt;p&gt;Not everyone is totally on-board with the principles of this new framework though. One day after the release of Crank.js was announced &lt;a href="https://www.reddit.com/r/javascript/comments/g1zj87/crankjs_an_alternative_to_reactjs_with_built_in/fnktdyg/?context=8&amp;amp;depth=9"&gt;on Reddit&lt;/a&gt;, Dan Abramov, a lead React contributor, came out in defense of React. He explained that React’s component-purity-driven philosophy is only a means to solving a problem of the end user: it’s nice to be able to render components before they appear on screen so that they paint faster. He said that one “can only really do those things safely when rendering is pure and safe to try at any time or interrupt”. Dan also argued that caching is not an ugly side effect of the Suspense API: Suspense was built around the use of a cache because caches improve the user experience by speeding up data fetching. However, he ultimately said that he “totally agrees with [the author of Crank.js] it’s great to have more options that explore various tradeoffs.”&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>react</category>
      <category>crankjs</category>
    </item>
    <item>
      <title>A quick question for people who use version control</title>
      <dc:creator>RobbieGM</dc:creator>
      <pubDate>Thu, 13 Feb 2020 17:40:45 +0000</pubDate>
      <link>https://forem.com/robbiegm/a-quick-question-for-people-who-use-version-control-2a6k</link>
      <guid>https://forem.com/robbiegm/a-quick-question-for-people-who-use-version-control-2a6k</guid>
      <description>&lt;p&gt;In my team, we use git branching to keep different features separate (of course). However, one co-worker insists on keeping these features in different files as well to avoid merge conflicts. For example, we may have a FormView.java on master, but in have both a FormView.java and a ValidatedFormView.java on the form-validation branch. I suggested that rather than duplicating files to "work around" git, we should let git do its thing and merge features when we want to. He also wants to keep duplicates in order to be able merge some parts of a feature into other branches without having to deal with merging the FormView.java file itself.&lt;/p&gt;

&lt;p&gt;What should we do? If he is right, why? If I am right, how can I convince him as such?&lt;/p&gt;

</description>
      <category>git</category>
      <category>versioncontrol</category>
      <category>help</category>
      <category>watercooler</category>
    </item>
  </channel>
</rss>
