<?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: Ihor Maslov</title>
    <description>The latest articles on DEV Community by Ihor Maslov (@ihormaslov).</description>
    <link>https://dev.to/ihormaslov</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%2F280853%2Fbefab61b-d097-4b62-918a-d303c963a9c8.png</url>
      <title>DEV Community: Ihor Maslov</title>
      <link>https://dev.to/ihormaslov</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/ihormaslov"/>
    <language>en</language>
    <item>
      <title>Yet another way to structure React Project.</title>
      <dc:creator>Ihor Maslov</dc:creator>
      <pubDate>Mon, 15 Mar 2021 20:05:32 +0000</pubDate>
      <link>https://dev.to/ihormaslov/yet-another-way-to-structure-react-project-28de</link>
      <guid>https://dev.to/ihormaslov/yet-another-way-to-structure-react-project-28de</guid>
      <description>&lt;p&gt;I adopted the structure &lt;a href="https://reactjs.org/docs/faq-structure.html#grouping-by-features-or-routes"&gt;recommended by React&lt;/a&gt; and improved it a little bit. At least, I think it was improved :)&lt;/p&gt;

&lt;h3&gt;
  
  
  The improved structure.
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;./src
├── App.css
├── App.js
├── App.test.js
├── README.md
├── apps
│   └── account
│       ├── components
│       │   ├── SignInDialog
│       │   │   └── index.js
│       │   ├── SignInForm
│       │   │   └── index.js
│       ├── hooks
│       │   └── useCreateUserWithEmailAndPassword.js
│       ├── pages
│       │   ├── SingIn
│       │   │   ├── index.js
│       │   │   └── styles.js
│       │   └── User
│       │       └── index.js
│       └── routes.js
├── index.js
└── routes.js
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I am going to locate together pages that are related to some entities in a project.&lt;br&gt;
In the example above:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;account&lt;/code&gt; - is the project entity&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;components&lt;/code&gt; - components that are common for pages in this entity&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;hook&lt;/code&gt; - custom hook for encapsulating some business logic&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;pages&lt;/code&gt; - components that are used in React Router &lt;a href="https://reactrouter.com/web/api/Route"&gt;Route&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;routes.js&lt;/code&gt; - route config for &lt;code&gt;account&lt;/code&gt; entity.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The &lt;code&gt;routes.js&lt;/code&gt; in the root &lt;code&gt;./src&lt;/code&gt; directory is the main URLs config containing all apps' routes. &lt;a href="https://dev.to/ihormaslov/reverse-patterns-to-url-react-router-config-2gb8"&gt;Read more details about URL config&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;This structure will be easy to scale by adding new project entities in the &lt;code&gt;apps&lt;/code&gt; directory.&lt;br&gt;
The above structure does not represent the entire project structure. A project can contain a lot more directories for shared components, hooks, assets, and others.&lt;/p&gt;

&lt;p&gt;Feedback is welcome!&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Reverse patterns to URL. React router Config.</title>
      <dc:creator>Ihor Maslov</dc:creator>
      <pubDate>Mon, 15 Mar 2021 20:04:55 +0000</pubDate>
      <link>https://dev.to/ihormaslov/reverse-patterns-to-url-react-router-config-2gb8</link>
      <guid>https://dev.to/ihormaslov/reverse-patterns-to-url-react-router-config-2gb8</guid>
      <description>&lt;p&gt;In this post, I would like to introduce my approach to "Named URLs" for &lt;a href="https://reactrouter.com/"&gt;React Router&lt;/a&gt;.&lt;/p&gt;

&lt;h1&gt;
  
  
  Motivation
&lt;/h1&gt;

&lt;p&gt;I used to use Django's URLs &lt;a href="https://docs.djangoproject.com/en/3.1/ref/urlresolvers/#reverse"&gt;&lt;code&gt;reverse&lt;/code&gt;&lt;/a&gt; function. This function is beneficial when you need to get an actual URL using a named URL pattern or callable view object.&lt;br&gt;
I want to use a similar approach with &lt;a href="https://reactrouter.com/"&gt;React Router&lt;/a&gt;.&lt;/p&gt;
&lt;h1&gt;
  
  
  Problems
&lt;/h1&gt;

&lt;p&gt;The problems I am trying to solve are:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Avoid hard-coded URLs&lt;/strong&gt;. In the most examples I found, URLs hard-coded in &lt;a href="https://reactrouter.com/web/api/Link"&gt;&lt;code&gt;Link&lt;/code&gt;&lt;/a&gt;. I feel like this can lead us to broken links during refactoring, etc.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Missing URL params&lt;/strong&gt;. It is difficult to identify Hard-coded links with missed params until you click on them.&lt;/li&gt;
&lt;/ol&gt;
&lt;h1&gt;
  
  
  Solution
&lt;/h1&gt;

&lt;p&gt;The project directories are structured &lt;a href="https://dev.to/ihormaslov/yet-another-way-to-structure-react-project-28de"&gt;this way&lt;/a&gt;. &lt;/p&gt;
&lt;h3&gt;
  
  
  The &lt;code&gt;Reverse&lt;/code&gt; implementation.
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// src/shared/utils/namedUrls.js

import { compile } from 'path-to-regexp';

export class RoutePath {
  reverse(params) {
    const reversed = compile(this.pattern);
    return reversed(params);
  }

  constructor(pattern, component) {
    if (!pattern || !component) throw new Error('`pattern` and `component` are required');
    this.pattern = pattern;
    this.component = component;
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;This class helps us build a route that knows how to build a link using given parameters and patterns.&lt;/p&gt;
&lt;h3&gt;
  
  
  The usage.
&lt;/h3&gt;

&lt;p&gt;In the app directory.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// src/apps/account/routes.js

import SignInPage from 'apps/account/pages/SignIn';
import UserPage from 'apps/account/pages/User';
import { RoutePath } from 'shared/utils/namedUrls';

const basePath = '/account/';
export default {
  signIn: new RoutePath(`${basePath}sign-in/`, SignInPage),
  user: new RoutePath(`${basePath}user/:id/`, UserPage),
};
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the main &lt;code&gt;routes.js&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// src/routes.js

import { prepareRoutes } from 'shared/utils/namedUrls';

import accountRoutes from './apps/account/routes';

export const routes = {
  accountRoutes,
};

export const preparedRoutes = prepareRoutes(routes);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In components&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import React from 'react';
import { Link } from 'react-router-dom';
import { routes } from 'routes';

const SomeComponent = () =&amp;gt; (
  &amp;lt;&amp;gt;
    &amp;lt;Link to={routes.accountRoutes.signIn.reverse()}&amp;gt;Sign In&amp;lt;/Link&amp;gt;
    &amp;lt;Link to={routes.accountRoutes.user.reverse({ id: 1 })}&amp;gt;User&amp;lt;/Link&amp;gt;
  &amp;lt;/&amp;gt;
);

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

&lt;/div&gt;



&lt;p&gt;Rendered links are:&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;a href="/account/sign-in/"&amp;gt;Sign In&amp;lt;/a&amp;gt;
&amp;lt;a href="/account/user/1/"&amp;gt;User&amp;lt;/a&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Error handling
&lt;/h3&gt;

&lt;p&gt;I didn't implement any additional error handling as I am satisfied with the &lt;code&gt;path-to-regexp&lt;/code&gt; app's error handling. &lt;br&gt;
If you miss some URL pattern parameters, you will find errors like the below in the browser console.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;index.ts:337 Uncaught TypeError: Expected "id" to be a string
    at index.ts:337
    at RoutePath.reverse (namedUrls.js:12)
    at App (App.js:62)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I suppose this will be enough to warn developers that they missed the URL pattern's parameters. And I feel like these errors should be helpful during e2e testing.&lt;/p&gt;

&lt;p&gt;Feedback is welcome!&lt;/p&gt;

</description>
      <category>react</category>
      <category>router</category>
      <category>javascript</category>
      <category>webdev</category>
    </item>
  </channel>
</rss>
