8 Practices In React that will Crash your application

8 Practices In React that will Crash your application

Carelessly checking if arrays exist before rendering If you have a habit of doing this: Then make sure you at least have unit tests to keep your eyes on that code at all times or handle arr correctly early on before passing it to the render method, or else the app will crash if arr becomes an object literal.

A lot of us have fallin in love with the react library for several reasons. It can be incredibly painless to create complex interactive user interfaces. The greatest part of it all is being able to compose components right on top of another without breaking other composed components.

And it's amazing that even social media giants like Facebook, Instagram and Pinterest made heavy use of them while creating a seamless user experience with huge APIs like Google Maps.

If you're currently building an application using react or thinking of using react for upcoming projects, then this tutorial is for you. I hope this tutorial will help you on your journey to make great react applications too by exposing a few code implementations that you ought to think twice about.

Without further ado, here are 8 Practices In React That Will Crash Your App In The Future:

1. Carelessly Checking Empty Objects When Rendering

Something I used to do long ago in the golden days when conditionally rendering components is to check if data had been populated in objects using Object.keys. And if there were data, then the component would continue to render if the condition passes:

const SomeComponent = ({ children, items = {}, isVisible }) => (
  <div>
    {Object.keys(items).length ? (
      <DataTable items={items} />
    ) : (
      <h2>Data has not been received</h2>
    )}
  </div>
)

Lets pretend that we called some API and received items as an object somewhere in the response. With that said, this may seem perfectly fine at first. The expected type of items is an object so it would be perfectly fine to use Object.keys with it. After all, we did initialize items to an empty object as a defense mechanism if a bug were to ever appear that turned it into a falsey value.

But we shouldn't trust the server to always return the same structure. What if items became an array in the future? Object.keys(items) would not crash but would return a weird output like ["0", "1", "2"]. How do you think the components being rendered with that data will react?

But that's not even the worst part. The worst part in the snippet is that if items was received as a null value in the props, then items will not even be initiated to the default value you provided!

And then your app will crash before it begins to do anything else:

"TypeError: Cannot convert undefined or null to object
    at Function.keys (<anonymous>)
    at yazeyafabu.js:4:45
    at https://static.jsbin.com/js/prod/runner-4.1.7.min.js:1:13924
    at https://static.jsbin.com/js/prod/runner-4.1.7.min.js:1:10866"

Again, please be careful!

2. Declaring Default Parameters Over Null

I was once guilty of spending a good amount of time debugging something similar to this:

const SomeComponent = ({ items = [], todaysDate, tomorrowsDate }) => {
  const [someState, setSomeState] = useState(null)

  return (
    <div>
      <h2>Today is {todaysDate}</h2>
      <small>And tomorrow is {tomorrowsDate}</small>
      <hr />
      {items.map((item, index) => (
        <span key={`item_${index}`}>{item.email}</span>
      ))}
    </div>
  )
}

const App = ({ dates, ...otherProps }) => {
  let items
  if (dates) {
    items = dates ? dates.map((d) => new Date(d).toLocaleDateString()) : null
  }

  return (
    <div>
      <SomeComponent {...otherProps} items={items} />
    </div>
  )
}

Inside our App component, if dates ends up being falsey, it will be initialized with null.

If you're like me, our instincts tell us that items should be initialized to an empty array by default if it was a falsey value. But our app will crash when dates is falsey because items is null. What?

Default function parameters allow named parameters to become initialized with default values if no value or undefined is passed!

In our case, even though null is falsey, it's still a value!

So the next time you set a default value to null, just make sure to think twice when you do that. You can simply just initialize a value to an empty array if that is the expected type of the value.

3. Grabbing Properties With Square Brackets

Sometimes the way properties are being grabbed may influence the behavior of the app. If you're wondering what that behavior is, it's the app crashing. Here is an example of performing object lookups with square brackets:

const someFunction = function() {
  return {
    names: ['bob', 'joe'],
    foods: ['apple', 'pineapple'],
  }
}

const obj = someFunction()
const names = obj['names']

console.log(names)
// result: ['bob', 'joe']

These are actually 100% valid use cases and there's nothing really wrong with them besides being slower than object key lookups.

Anyhow, the real problem starts to creep up on your app the more you go deeper with the lookups:

const someFunction = function() {
  return {
    names: ['bob', 'joe'],
    foods: ['apple', 'pineapple'],
  }
}

const obj = someFunction()
const names = obj['names']

console.log(names)
// result: ['bob', 'joe']

console.log(names.joe)
// result: undefined

However, it's a little hard to explain the severity of this practice without a real world example. So I'm going to bring up a real world example. The code example I am about to show you was taken from a repository that dates 8 months back from today. To protect some of the privacy that this code originated from, I renamed almost every variable but the code design, syntax and architecture stayed exactly the same:

import { createSelector } from 'reselect'

// supports passing in the whole obj or just the string to correct the video type
const fixVideoTypeNaming = (videoType) => {
  let video = videoType

  // If video is a video object
  if (video && typeof video === 'object') {
    const media = { ...video }
    video = media.videoType
  }

  // If video is the actual videoType string
  if (typeof video === 'string') {
    // fix the typo because brian is an idiot
    if (video === 'mp3') {
      video = 'mp4'
    }
  }

  return video
}

/* -------------------------------------------------------
  ---- Pre-selectors
-------------------------------------------------------- */

export const getOverallSelector = (state) =>
  state.app[fixVideoTypeNaming(state.app.media.video.videoType)].options.total
    .overall

export const getSpecificWeekSelector = (state, props) =>
  state.app[fixVideoTypeNaming(state.app.media.video.videoType)].options.weekly[
    props.date
  ]

/* -------------------------------------------------------
  ---- Selectors
-------------------------------------------------------- */

export const getWeeklyCycleSelector = createSelector(
  getSpecificWeekSelector,
  (weekCycle) => weekCycle || null,
)

export const getFetchingTotalStatusSelector = createSelector(
  (state) =>
    state.app[fixVideoTypeNaming(state.app.media.video.videoType)].options.total
      .fetching,
  (fetching) => fetching,
)

export const getFetchErrorSelector = createSelector(
  (state) =>
    state.app[fixVideoTypeNaming(state.app.media.video.videoType)].options.total
      .fetchError,
  (fetchError) => fetchError,
)

fixVideoTypeNaming is a function that will extract the video type based on the value passed in as arguments. If the argument is a video object, it will extract the video type from the .videoType property. If it is a string, then the caller passed in the videoType so we can skip first step. Someone has found that the videoType .mp4 property had been mispelled in several areas of the app. For a quick temporary fix around the issue, fixVideoTypeNaming was used to patch that typo.

Now as some of you might have guessed, the app was built with redux (hence the syntax).

And to use these selectors, you would import them to use in a connect higher order component to attach a component to listen to that slice of the state.

const withTotalCount = (WrappedComponent) => {
  class WithTotalCountContainer extends React.Component {
    componentDidMount = () => {
      const { total, dispatch } = this.props
      if (total == null) {
        dispatch(fetchTotalVideoTypeCount())
      }
    }

    render() {
      return <WrappedComponent {...this.props} />
    }
  }

  WithTotalCountContainer.propTypes = {
    fetching: PropTypes.bool.isRequired,
    total: PropTypes.number,
    fetchError: PropTypes.object,
    dispatch: PropTypes.func.isRequired,
  }

  WithTotalCountContainer.displayName = `withTotalCount(${getDisplayName(
    WrappedComponent,
  )})`

  return connect((state) => {
    const videoType = fixVideoTypeNaming(state.app.media.video.videoType)
    const { fetching, total, fetchError } = state.app.media.video[
      videoType
    ].options.total

    return { fetching, total, fetchError }
  })(WithTotalCountContainer)
}

UI Component:

const TotalVideoCount = ({ classes, total, fetching, fetchError }) => {
  if (fetching) return <LoadingSpinner />
  const hasResults = !!total
  const noResults = fetched && !total
  const errorOccurred = !!fetchError

  return (
    <Typography
      variant="h3"
      className={classes.root}
      error={!!fetched && !!fetchError}
      primary={hasResults}
      soft={noResults || errorOccurred}
      center
    >
      {noResults && 'No Results'}
      {hasResults && `$${formatTotal(total)}`}
      {errorOccurred && 'An error occurred.'}
    </Typography>
  )
}

The component receives all of the props that the HOC passes to it and displays information following the conditions adapting from the data given from the props. In a perfect world, this would be fine. In a non-perfect world, this would temporarily be fine.

If we go back to the container and look at the way the selectors are selecting their values, we actually might have planted a ticking timebomb waiting for an open opportunity to attack:

export const getOverallSelector = (state) =>
  state.app[fixVideoTypeNaming(state.app.media.video.videoType)].options.total
    .overall

export const getSpecificWeekSelector = (state, props) =>
  state.app[fixVideoTypeNaming(state.app.media.video.videoType)].options.weekly[
    props.date
  ]

When developing any sort of application, common practices to ensure higher level of confidence and diminishing bugs during the development flow is implementing tests in-between to ensure that the application is working as intended.

In the case of these code snippets however, if they aren't tested, the app will crash in the future if not handled early.

For one, state.app.media.video.videoType is four levels deep in the chain. What if another developer accidentally made a mistake when he was asked to fix another part of the app and state.app.media.video becomes undefined? The app will crash because it can't read the property videoType of undefined.

In addition, if there was another typo issue with a videoType and fixVideoTypeNaming isn't updated to accomodate that along with the mp3 issue, the app risks another unintentional crash that no one would have been able to detect unless a real user comes across the issue. And by that time, it would be too late.

And it's never a good practice to assume that the app will never ever come across bugs like these. Please be careful!

4. Carelessly Checking If Arrays Exist Before Rendering

This can be a very similar situation as with #3, but arrays and objects are used quite often interchangeably that they deserve their own sections.

If you have a habit of doing this:

render() {
  const { arr } = this.props
  return (
    <div>
      {arr && arr.map()...}
    </div>
  )
}

Then make sure you at least have unit tests to keep your eyes on that code at all times or handle arr correctly early on before passing it to the render method, or else the app will crash if arr becomes an object literal. Of course the && operator will consider it as truthy and attempt to .map the object literal which will end up crashing the entire app.

So please keep this in mind. Save your energy and frustrations for bigger problems that deserve more of your special attention! ;)

5. Not Using a Linter

If you aren't using any type of linter while you're developing apps or you simply don't know what they are, allow me to elaborate a little about why they are useful in development.

The linter I use to assist me in my development flow is ESLint, a very known linting tool for JavaScript that allows developers to discover problems with their code without even executing them.

This tool is so useful that it can act as your semi-mentor as it helps correct your mistakes in real time--as if someone is mentoring you. It even describes why your code can be bad and suggests what you should do to replace them with!

Here's an example:

The coolest thing about eslint is that if you don't like certain rules or don't agree with some of them, you can simple disable certain ones so that they no longer show up as linting warnings/errors as you're developing. Whatever makes you happy, right?

6. Destructuring When Rendering Lists

I've seen this happen to several people in the past and it isn't always an easy bug to detect. Basically when you have a list of items and you're going to render a bunch of components for each one in the list, the bug that can creep up on your app is that if there comes a time in the future where one of the items in the list is not a value you expect it to be, your app may crash if it doesn't know how to handle the value type.

Here's an example:

const api = {
  async getTotalFrogs() {
    return {
      data: {
        result: [
          { name: 'bob the frog', tongueWidth: 50, weight: 8 },
          { name: 'joe the other frog', tongueWidth: 40, weight: 5 },
          { name: 'kelly the last frog', tongueWidth: 20, weight: 2 },
        ],
      },
    }
  },
}

const getData = async ({ withTongues = false }) => {
  try {
    const response = await api.getTotalFrogs({ withTongues })
    return response.data.result
  } catch (err) {
    throw err
  }
}

const DataList = (props) => {
  const [items, setItems] = useState([])
  const [error, setError] = useState(null)

  React.useEffect(() => {
    getData({ withTongues: true })
      .then(setItems)
      .catch(setError)
  }, [])

  return (
    <div>
      {Array.isArray(items) && (
        <Header size="tiny" inverted>
          {items.map(({ name, tongueWidth, weight }) => (
            <div style={{ margin: '25px 0' }}>
              <div>Name: {name}</div>
              <div>Width of their tongue: {tongueWidth}cm</div>
              <div>Weight: {weight}lbs</div>
            </div>
          ))}
        </Header>
      )}
      {error && <Header>You received an error. Do you need a linter?</Header>}
    </div>
  )
}

The code would work perfectly fine. Now if we look at the api call and instead of returning this:

const api = {
  async getTotalFrogs() {
    return {
      data: {
        result: [
          { name: 'bob the frog', tongueWidth: 50, weight: 8 },
          { name: 'joe the other frog', tongueWidth: 40, weight: 5 },
          { name: 'kelly the last frog', tongueWidth: 20, weight: 2 },
        ],
      },
    }
  },
}

What if somehow there was an issue with how the data flow was handled when an unexpected condition occurred in the api client and returned this array instead?

const api = {
  async getTotalFrogs() {
    return {
      data: {
        result: [
          { name: 'bob the frog', tongueWidth: 50, weight: 8 },
          undefined,
          { name: 'kelly the last frog', tongueWidth: 20, weight: 2 },
        ],
      },
    }
  },
}

Your app will crash because it doesn't know how to handle that:

Uncaught TypeError: Cannot read property 'name' of undefined
    at eval (DataList.js? [sm]:65)
    at Array.map (<anonymous>)
    at DataList (DataList.js? [sm]:64)
    at renderWithHooks (react-dom.development.js:12938)
    at updateFunctionComponent (react-dom.development.js:14627)

So to prevent your app from crashing instead, you can set a default object on each iteration:

{
  items.map(({ name, tongueWidth, weight } = {}) => (
    <div style={{ margin: '25px 0' }}>
      <div>Name: {name}</div>
      <div>Width of their tongue: {tongueWidth}cm</div>
      <div>Weight: {weight}lbs</div>
    </div>
  ))
}

And now your users won't have to make judgements about your technology and expertise when they don't see a page crashing in front of them:

However, even though the app no longer crashes I recommend to go further and handle the missing values like returning null for entire items that have similar issues instead, since there isn't any data in them anyways.

7. Not Researching Enough About What You're Going To Implement

One crucial mistake i've made in the past was being overly confident with a search input I had implemented, trusting my opinions too early in the game.

What do I mean by this? Well, its not the search input component that I was overly confident with. The component should have been an easy task... and it was.

The real culprit of an issue that occurred with the whole the search functionality was the characters being included in the queries.

When we're sending keywords as queries to a search API, it's not always sufficient to think that every key the user types is valid, even though they're on the keyboard for that reason.

Just be 100% sure that a regex like this works just as intended and avoids leaving out any invalid characters that can crash your app:

const hasInvalidChars = /^.*?(?=[\+\^#%&$\*:<>\?/\{\|\}\[\]\\\)\(]).*$/g.test(
  inputValue,
)

That example is the most up to date, established regular expression for a search API.

Here is what it was before:

const hasInvalidChars = /^.*?(?=[\+\^#%&$\*:<>\?/\{\|\}\[\]\)\(]).*$/g.test(
  inputValue,
)

const callApi = async (keywords) => {
  try {
    const url = `https://someapi.com/v1/search/?keywords=${keywords}/`
    return api.searchStuff(url)
  } catch (error) {
    throw error
  }
}

As you can see the slash / is missing, and that was causing the app to crash! if that character ends up being sent to an API over the wire, guess what the API thinks the URL is going to be?

Also, I wouldn't put 100% of my trust in the examples you find on the internet. A lot of them aren't fully tested solutions and there isn't really a standard for majority of use cases when it comes to regular expressions.

8. Not Restricting The Sizes of File Inputs

Restricting the sizes of files that users select is a good practice because most of the time you don't really need a rediculously large file when it can be compressed in some way without losing any noticeable signs of reduction in quality.

But there's a more important reason why restricting sizes to a certain limit is a good practice. At my company, we've noticed users in the past occasionally get "frozen" while their images are being uploaded. Not everyone has an Alienware 17 R5 in their possession, so you must take certain circumstances of your users in consideration.

Here's an example of restricting files to a limit of 5 MB (5,000,000 bytes):

import React, { useState, useEffect } from 'react'

const useUploadStuff = () => {
  const [files, setFiles] = useState([])

  // Limit the file sizes here
  const onChange = (e) => {
    const arrFiles = Array.from(e.target.files)
    const filesUnder5mb = arrFiles.filter((file) => {
      const bytesLimit = 5000000
      if (file.size > bytesLimit) {
        // optionally process some UX about this file size
      }
      return file.size < bytesLimit
    })
    setFiles(filesUnder5mb)
  }

  useEffect(() => {
    if (files.length) {
      // do something with files
    }
  }, [files])

  return {
    files,
    onChange,
  }
}

const UploadStuff = () => {
  const { onChange } = useUploadStuff()

  return (
    <div>
      <h2 style={{ color: '#fff' }}>Hi</h2>
      <div>
        <input
          style={{ color: '#fff' }}
          onChange={onChange}
          type="file"
          placeholder="Upload Stuff"
          multiple
        />
      </div>
    </div>
  )
}

export default UploadStuff

You wouldn't want users to be uploading video games when they're supposed to be uploading documents!

Conclusion

And that concludes the end of this post! Thank you for reading !

Angular 9 Tutorial: Learn to Build a CRUD Angular App Quickly

What's new in Bootstrap 5 and when Bootstrap 5 release date?

What’s new in HTML6

How to Build Progressive Web Apps (PWA) using Angular 9

What is new features in Javascript ES2020 ECMAScript 2020

Best Practices for using Typescript with React

Best Practices for using Typescript with React

React and TypeScript are two awesome technologies used by a lot of developers these days. It can be tricky to work with React and TypeScript and find the right answers, so we've put together the best practices and examples to clear your doubts.

React and TypeScript are two awesome technologies used by a lot of developers these days. Knowing how to do things can get tricky, and sometimes it’s hard to find the right answer. Not to worry. We’ve put together the best practices along with examples to clarify any doubts you may have.

Let’s dive in!

How React and TypeScript Work Together

Before we begin, let’s revisit how React and TypeScript work together. React is a “JavaScript library for building user interfaces”, while TypeScript is a “typed superset of JavaScript that compiles to plain JavaScript.” By using them together, we essentially build our UIs using a typed version of JavaScript.

The reason you might use them together would be to get the benefits of a statically typed language (TypeScript) for your UI. This means more safety and fewer bugs shipping to the front end.

Does TypeScript Compile My React Code?

A common question that’s always good to review is whether TypeScript compiles your React code. The way TypeScript works is similar to this interaction:

TS: “Hey, is this all your UI code?”
React: “Yup!”
TS: “Cool! I’m going to compile it and make sure you didn’t miss anything.”
React: “Sounds good to me!”

So the answer is yes, it does! But later, when we cover the tsconfig.json settings, most of the time you’ll want to use "noEmit": true. What this means is TypeScript will not emit JavaScript out after compilation. This is because typically, we’re just utilizing TypeScript to do our type-checking.

The output is handled, in a CRA setting, by react-scripts. We run yarn build and react-scripts bundles the output for production.

To recap, TypeScript compiles your React code to type-check your code. It doesn’t emit any JavaScript output (in most scenarios). The output is still similar to a non-TypeScript React project.

Can TypeScript Work with React and webpack?

Yes, TypeScript can work with React and webpack. Lucky for you, the official TypeScript Handbook has a guide on that.

Hopefully, that gives you a gentle refresher on how the two work together. Now, on to best practices!

Best Practices

We’ve researched the most common questions and put together this handy list of the most common use cases for React with TypeScript. This way, you can follow best practices in your projects by using this article as a reference.

Configuration

One of the least fun, yet most important parts of development is configuration. How can we set things up in the shortest amount of time that will provide maximum efficiency and productivity? We’ll discuss project setup including:

  • tsconfig.json
  • ESLint
  • Prettier
  • VS Code extensions and settings.

Project Setup

The quickest way to start a React/TypeScript app is by using create-react-app with the TypeScript template. You can do this by running:

npx create-react-app my-app --template typescript

This will get you the bare minimum to start writing React with TypeScript. A few noticeable differences are:

  • the .tsx file extension
  • the tsconfig.json
  • the react-app-env.d.ts

The tsx is for “TypeScript JSX”. The tsconfig.json is the TypeScript configuration file, which has some defaults set. The react-app-env.d.ts references the types of react-scripts, and helps with things like allowing for SVG imports.

tsconfig.json

Lucky for us, the latest React/TypeScript template generates tsconfig.json for us. However, they add the bare minimum to get started. We suggest you modify yours to match the one below. We’ve added comments to explain the purpose of each option as well:

{
  "compilerOptions": {
    "target": "es5", // Specify ECMAScript target version
    "lib": [
      "dom",
      "dom.iterable",
      "esnext"
    ], // List of library files to be included in the compilation
    "allowJs": true, // Allow JavaScript files to be compiled
    "skipLibCheck": true, // Skip type checking of all declaration files
    "esModuleInterop": true, // Disbles namespace imports (import * as fs from "fs") and enables CJS/AMD/UMD style imports (import fs from "fs")
    "allowSyntheticDefaultImports": true, // Allow default imports from modules with no default export
    "strict": true, // Enable all strict type checking options
    "forceConsistentCasingInFileNames": true, // Disallow inconsistently-cased references to the same file.
    "module": "esnext", // Specify module code generation
    "moduleResolution": "node", // Resolve modules using Node.js style
    "resolveJsonModule": true, // Include modules imported with .json extension
    "isolatedModules": true, // Transpile each file as a separate module
    "noEmit": true, // Do not emit output (meaning do not compile code, only perform type checking)
    "jsx": "react" // Support JSX in .tsx files
    "sourceMap": true, // *** Generate corrresponding .map file ***
    "declaration": true, // *** Generate corresponding .d.ts file ***
    "noUnusedLocals": true, // *** Report errors on unused locals ***
    "noUnusedParameters": true, // *** Report errors on unused parameters ***
    "experimentalDecorators": true // *** Enables experimental support for ES decorators ***
    "incremental": true // *** Enable incremental compilation by reading/writing information from prior compilations to a file on disk ***
        "noFallthroughCasesInSwitch": true // *** Report errors for fallthrough cases in switch statement ***
  },
  "include": [
    "src/**/*" // *** The files TypeScript should type check ***
  ],
  "exclude": ["node_modules", "build"] // *** The files to not type check ***
}

The additional recommendations come from the [react-typescript-cheatsheet community and the explanations come from the Compiler Options docs in the Official TypeScript Handbook. This is a wonderful resource if you want to learn about other options and what they do.

ESLint/Prettier

In order to ensure that your code follows the rules of the project or your team, and the style is consistent, it’s recommended you set up ESLint and Prettier. To get them to play nicely, follow these steps to set it up.

  1. Install the required dev dependencies:

    yarn add eslint @typescript-eslint/parser @typescript-eslint/eslint-plugin eslint-plugin-react --dev
    
    
  2. Create a .eslintrc.js file at the root and add the following:

    module.exports =  {
      parser:  '@typescript-eslint/parser',  // Specifies the ESLint parser
      extends:  [
        'plugin:react/recommended',  // Uses the recommended rules from @eslint-plugin-react
        'plugin:@typescript-eslint/recommended',  // Uses the recommended rules from @typescript-eslint/eslint-plugin
      ],
      parserOptions:  {
      ecmaVersion:  2018,  // Allows for the parsing of modern ECMAScript features
      sourceType:  'module',  // Allows for the use of imports
      ecmaFeatures:  {
        jsx:  true,  // Allows for the parsing of JSX
      },
      },
      rules:  {
        // Place to specify ESLint rules. Can be used to overwrite rules specified from the extended configs
        // e.g. "@typescript-eslint/explicit-function-return-type": "off",
      },
      settings:  {
        react:  {
          version:  'detect',  // Tells eslint-plugin-react to automatically detect the version of React to use
        },
      },
    };
    
    
  3. Add Prettier dependencies:

    yarn add prettier eslint-config-prettier eslint-plugin-prettier --dev
    
    
  4. Create a .prettierrc.js file at the root and add the following:

    module.exports =  {
      semi:  true,
      trailingComma:  'all',
      singleQuote:  true,
      printWidth:  120,
      tabWidth:  4,
    };
    
    
  5. Update the .eslintrc.js file:

    module.exports =  {
      parser:  '@typescript-eslint/parser',  // Specifies the ESLint parser
      extends:  [
        'plugin:react/recommended',  // Uses the recommended rules from @eslint-plugin-react
        'plugin:@typescript-eslint/recommended',  // Uses the recommended rules from the @typescript-eslint/eslint-plugin
    +   'prettier/@typescript-eslint',  // Uses eslint-config-prettier to disable ESLint rules from @typescript-eslint/eslint-plugin that would conflict with prettier
    +   'plugin:prettier/recommended',  // Enables eslint-plugin-prettier and displays prettier errors as ESLint errors. Make sure this is always the last configuration in the extends array.
      ],
      parserOptions:  {
      ecmaVersion:  2018,  // Allows for the parsing of modern ECMAScript features
      sourceType:  'module',  // Allows for the use of imports
      ecmaFeatures:  {
        jsx:  true,  // Allows for the parsing of JSX
      },
      },
      rules:  {
        // Place to specify ESLint rules. Can be used to overwrite rules specified from the extended configs
        // e.g. "@typescript-eslint/explicit-function-return-type": "off",
      },
      settings:  {
        react:  {
          version:  'detect',  // Tells eslint-plugin-react to automatically detect the version of React to use
        },
      },
    };
    
    

These recommendations come from a community resource written called “Using ESLint and Prettier in a TypeScript Project” by Robert Cooper. If you visit his blog, you can read more about the “why” behind these rules and configurations.

VSCode Extensions and Settings

We’ve added ESLint and Prettier and the next step to improve our DX is to automatically fix/prettify our code on save.

First, install the ESLint extension for VSCode. This will allow ESLint to integrate with your editor seamlessly.

Next, update your Workspace settings by adding the following to your .vscode/settings.json:

{
  "eslint.autoFixOnSave": true,
  "eslint.validate": [
    "javascript",
    "javascriptreact",
    { "language": "typescript", "autoFix": true },
    { "language": "typescriptreact", "autoFix": true }
  ],
  "editor.formatOnSave": true,
  "[javascript]": {
    "editor.formatOnSave": false
  },
  "[javascriptreact]": {
    "editor.formatOnSave": false
  },
  "[typescript]": {
    "editor.formatOnSave": false
  },
  "[typescriptreact]": {
    "editor.formatOnSave": false
  }
}

This will allow VS Code to work its magic and fix your code when you save. It’s beautiful!

These suggestions also come from the previously linked article “Using ESLint and Prettier in a TypeScript Project” by Robert Cooper.

Components

One of the core concepts of React is components. Here, we’ll be referring to standard components as of React v16.8, meaning ones that use hooks as opposed to classes.

In general, there’s much to be concerned with for basic components. Let’s look at an example:

import React from 'react'

// Written as a function declaration
function Heading(): React.ReactNode {
  return <h1>My Website Heading</h1>
}

// Written as a function expression
const OtherHeading: React.FC = () => <h1>My Website Heading</h1>

Notice the key difference here. In the first example, we’re writing our function as a function declaration. We annotate the return type with React.Node because that’s what it returns. In contrast, the second example uses a function expression. Because the second instance returns a function, instead of a value or expression, we annotate the function type with React.FC for React “Function Component”.

It can be confusing to remember the two. It’s mostly a matter of design choice. Whichever you choose to use in your project, use it consistently.

Props

The next core concept we’ll cover is props. You can define your props using either an interface or a type. Let’s look at another example:

import React from 'react'

interface Props {
  name: string;
  color: string;
}

type OtherProps = {
  name: string;
  color: string;
}

// Notice here we're using the function declaration with the interface Props
function Heading({ name, color }: Props): React.ReactNode {
  return <h1>My Website Heading</h1>
}

// Notice here we're using the function expression with the type OtherProps
const OtherHeading: React.FC<OtherProps> = ({ name, color }) =>
  <h1>My Website Heading</h1>

When it comes to types or interfaces, we suggest following the guidelines presented by the react-typescript-cheatsheet community:

  • “always use interface for public API’s definition when authoring a library or 3rd-party ambient type definitions.”
  • “consider using type for your React Component Props and State, because it is more constrained.”

You can read more about the discussion and see a handy table comparing types vs interfaces here.

Let’s look at one more example so we can see something a little bit more practical:

import React from 'react'

type Props = {
  /** color to use for the background */
  color?: string;
  /** standard children prop: accepts any valid React Node */
  children: React.ReactNode;
  /** callback function passed to the onClick handler*/
  onClick: ()  => void;
}

const Button: React.FC<Props> = ({ children, color = 'tomato', onClick }) => {
   return <button style={{ backgroundColor: color }} onClick={onClick}>{children}</button>
}

In this <Button /> component, we use a type for our props. Each prop has a short description listed above it to provide more context to other developers. The ? after the prop named color indicates that it’s optional. The children prop takes a React.ReactNode because it accepts everything that’s a valid return value of a component (read more here). To account for our optional color prop, we use a default value when destructuring it. This example should cover the basics and show you have to write types for your props and use both optional and default values.

In general, keep these things in mind when writing your props in a React and TypeScript project:

  • Always add descriptive comments to your props using the TSDoc notation /** comment */.
  • Whether you use types or interfaces for your component props, use them consistently.
  • When props are optional, handle appropriately or use default values.

Hooks

Luckily, the TypeScript type inference works well when using hooks. This means you don’t have much to worry about. For instance, take this example:

// `value` is inferred as a string
// `setValue` is inferred as (newValue: string) => void
const [value, setValue] = useState('')

TypeScript infers the values given to use by the useState hook. This is an area where React and TypeScript just work together and it’s beautiful.

On the rare occasions where you need to initialize a hook with a null-ish value, you can make use of a generic and pass a union to correctly type your hook. See this instance:

type User = {
  email: string;
  id: string;
}

// the generic is the < >
// the union is the User | null
// together, TypeScript knows, "Ah, user can be User or null".
const [user, setUser] = useState<User | null>(null);

The other place where TypeScript shines with Hooks is with userReducer, where you can take advantage of discriminated unions. Here’s a useful example:

type AppState = {};
type Action =
  | { type: "SET_ONE"; payload: string }
  | { type: "SET_TWO"; payload: number };

export function reducer(state: AppState, action: Action): AppState {
  switch (action.type) {
    case "SET_ONE":
      return {
        ...state,
        one: action.payload // `payload` is string
      };
    case "SET_TWO":
      return {
        ...state,
        two: action.payload // `payload` is number
      };
    default:
      return state;
  }
}

Source: react-typescript-cheatsheet Hooks section

The beauty here lies in the usefulness of discriminated unions. Notice how Action has a union of two similar-looking objects. The property type is a string literal. The difference between this and a type string is that the value must match the literal string defined in the type. This means your program is extra safe because a developer can only call an action that has a type key set to "SET_ONE" or "SET_TWO".

As you can see, Hooks don’t add much complexity to the nature of a React and TypeScript project. If anything, they lend themselves well to the duo.

Common Use Cases

This section is to cover the most common use cases where people stumble when using TypeScript with React. We hope by sharing this, you’ll avoid the pitfalls and even share this knowledge with others.

Handling Form Events

One of the most common cases is correctly typing the onChange used on an input field in a form. Here’s an example:

import React from 'react'

const MyInput = () => {
  const [value, setValue] = React.useState('')

  // The event type is a "ChangeEvent"
  // We pass in "HTMLInputElement" to the input
  function onChange(e: React.ChangeEvent<HTMLInputElement>) {
    setValue(e.target.value)
  }

  return <input value={value} onChange={onChange} id="input-example"/>
}

Extending Component Props

Sometimes you want to take component props declared for one component and extend them to use them on another component. But you might want to modify one or two. Well, remember how we looked at the two ways to type component props, types or interfaces? Depending on which you used determines how you extend the component props. Let’s first look at the way using type:

import React from 'react';

type ButtonProps = {
    /** the background color of the button */
    color: string;
    /** the text to show inside the button */
    text: string;
}

type ContainerProps = ButtonProps & {
    /** the height of the container (value used with 'px') */
    height: number;
}

const Container: React.FC<ContainerProps> = ({ color, height, width, text }) => {
  return <div style={{ backgroundColor: color, height: `${height}px` }}>{text}</div>
}

If you declared your props using an interface, then we can use the keyword extends to essentially “extend” that interface but make a modification or two:

import React from 'react';

interface ButtonProps {
    /** the background color of the button */
    color: string;
    /** the text to show inside the button */
    text: string;
}

interface ContainerProps extends ButtonProps {
    /** the height of the container (value used with 'px') */
    height: number;
}

const Container: React.FC<ContainerProps> = ({ color, height, width, text }) => {
  return <div style={{ backgroundColor: color, height: `${height}px` }}>{text}</div>
}

Both methods solve the problem. It’s up to you to decide which to use. Personally, extending an interface feels more readable, but ultimately, it’s up to you and your team.

You can read more about both concepts in the TypeScript Handbook:

Third-party Libraries

Whether it’s for a GraphQL client like Apollo or for testing with something like React Testing Library, we often find ourselves using third-party libraries in React and TypeScript projects. When this happens, the first thing you want to do is see if there’s a @types package with the TypeScript type definitions. You can do so by running:

#yarn
yarn add @types/<package-name>

#npm
npm install @types/<package-name>

For instance, if you’re using Jest, you can do this by running:

#yarn
yarn add @types/jest

#npm
npm install @types/jest

This would then give you added type-safety whenever you’re using Jest in your project.

The @types namespace is reserved for package type definitions. They live in a repository called DefinitelyTyped, which is partially maintained by the TypeScript team and partially the community.

Should these be saved as dependencies or devDependencies in my package.json?

The short answer is “it depends”. Most of the time, they can go under devDependencies if you’re building a web application. However, if you’re writing a React library in TypeScript, you may want to include them as dependencies.

There are a few answers to this on Stack Overflow, which you may check out for further information.

What happens if they don’t have a @types package?

If you don’t find a @types package on npm, then you essentially have two options:

  1. Add a basic declaration file
  2. Add a thorough declaration file

The first option means you create a file based on the package name and put it at the root. If, for instance, we needed types for our package banana-js, then we could create a basic declaration file called banana-js.d.ts at the root:

declare module 'banana-js';

This won’t provide you type safety but it will unblock you.

A more thorough declaration file would be where you add types for the library/package:

declare namespace bananaJs {
    function getBanana(): string;
    function addBanana(n: number) void;
    function removeBanana(n: number) void;
}

If you’ve never written a declaration file, then we suggest you take a look at the guide in the official TypeScript Handbook.

Summary

Using React and TypeScript together in the best way takes a bit of learning due to the amount of information, but the benefits pay off immensely in the long run. In this article, we covered configuration, components, props, hooks, common use cases, and third-party libraries. Although we could dive deeper into a lot of individual areas, this should cover the 80% needed to help you follow best practices.

7 Best Javascript Iframe Libraries

7 Best Javascript Iframe Libraries

Iframes let you build user experiences into embeddable ‘cross-domain components’, which let users interact with other sites without being redirected. I have compiled 7 best Javascript iframe libraries.

Iframes let you build user experiences into embeddable ‘cross-domain components’, which let users interact with other sites without being redirected. I have compiled 7 best Javascript iframe libraries.

1. Zoid

A cross-domain component toolkit, supporting:

  • Render an iframe or popup on a different domain, and pass down props, including objects and functions
  • Call callbacks natively from the child window without worrying about post-messaging or cross-domain restrictions
  • Create and expose components to share functionality from your site to others!
  • Render your component directly as a React, Vue or Angular component!
    It's 'data-down, actions up' style components, but 100% cross-domain using iframes and popups!

Download


2. Postmate

Postmate is a promise-based API built on postMessage. It allows a parent page to speak with a child iFrame across origins with minimal effort.

Download


3. Iframe Resizer

Keep same and cross domain iFrames sized to their content with support for window/content resizing, in page links, nesting and multiple iFrames

Demo

Download


4. Iframely

Embed proxy. Supports over 1800 domains via custom parsers, oEmbed, Twitter Cards and Open Graph

Demo

Download


5. React Frame component

This component allows you to encapsulate your entire React application or per component in an iFrame.

Demo

Download


6. Seamless.js

A seamless iframe makes it so that visitors are unable to distinguish between content within the iframe and content beside the iframe. Seamless.js is a JavaScript library (with no dependencies) that makes working with iframes easy by doing all the seamless stuff for you automatically.

Demo

Download


7. Porthole

A proxy to safely communicate to cross-domain iframes in javascript

Demo

Download


Thank for read!

10 Best React Loading Component for Your App

10 Best React Loading Component for Your App

If you are unable to shorten the process, you should at least try to make the wait pleasant for your users. Here are 10 react loading components for your react.js application

While instant feedback from an app or website is best, sometimes your product won't be able to adhere to speed guidelines. The slow response may be due to poor internet connection or the operation process may take a long time. For such cases, the designer must reassure the user that:
The application is working according to their requirements and the actual process is still active.

If you are unable to shorten the process, you should at least try to make the wait pleasant for your users. Here are 10 react loading components for your react.js application

1. Create React Content Loader

Have you heard about react-content-loader? It's a SVG component to create placeholder loading, like Facebook cards loading or also known as skeleton UI. So now you can use this online tool to create your own loader easily. You just need to draw using the canvas or code using the live editing!

View Demo: https://danilowoz.com/create-content-loader/

Github: https://github.com/danilowoz/create-content-loader

Download Link: https://github.com/danilowoz/create-content-loader/archive/master.zip

2. react-loading

React-Loading is a React-based Loading animation component library includes many exquisite and beautiful loading components. It will effectively relieve the user's anxiety when you give loading dynamics tips at the appropriate place and moment in your project. This component library supports on-demand loading, so pick a favorite Loading component now to enrich your project

View Demo: http://139.196.82.33:8080/iframe.html?id=demo--demo

Github: https://github.com/sixiaodong123/react-loading

Download Link: https://github.com/sixiaodong123/react-loading/archive/master.zip

3. react-simple-infinite-loading

Someone pointed out the React implementation of the list was a bit complex. I figure out it was possible to write an abstraction for this particular case. Here it is!

This component aims to stay easy to use. If your use case needs more options I recommend using directly awesome libraries from Brian Vaughn listed in dependencies section.

View Demo: https://codesandbox.io/s/magical-shockley-vhkz8

Github: https://github.com/frinyvonnick/react-simple-infinite-loading

Download Link: https://github.com/frinyvonnick/react-simple-infinite-loading/archive/master.zip

4. react-pure-loaders

React Pure Loaders is a package that disponibilizes loaders for your Project. Those loaders are used as components, using color and a loading variables as properties.

The component expects the to receive the color as a string with the hexadecimal code and the loading as a boolean, that is true by default.

View Demo: https://reactpureloaders.io/

Github: https://github.com/jameswlane/react-pure-loaders

Download Link: https://github.com/jameswlane/react-pure-loaders

5. react-loadcon

React component to manipulate the favicon, as a loading or progress indicator, for now. The idea of "Favicon as DOM" is under construction.

View Demo: https://foreseaz.github.io/react-loadcon/

Github: https://github.com/foreseaz/react-loadcon

Download Link: https://github.com/foreseaz/react-loadcon/archive/master.zip

6. React Nested Loader

The easiest way to manage loaders/errors inside a button. NOT an UI lib.

  • Manage loading/error state of nested views/buttons triggering async actions
  • Not an UI lib, you provide the UI. Works with ReactNative.
  • No boilerplate at all, no need to use setState/Redux

View Demo: https://codesandbox.io/s/w640yv5p9w

Github: https://github.com/slorber/react-nested-loader

Download Link: https://github.com/slorber/react-nested-loader/archive/master.zip

7. react-wait

react-wait is a React Hook helps to manage multiple loading states on the page without any conflict. It's based on a very simple idea that manages an Array of multiple loading states. The built-in loader component listens its registered loader and immediately become loading state.

View Demo: https://codesandbox.io/s/y3w5v5lk0j

Github: http://github.com/f/react-wait

Download Link: https://reactjsexample.com/complex-loader-management-hook-for-react/

8. React Redux Loading Bar

A React component that provides Loading Bar (aka Progress Bar) for long running tasks.

Consists of:

  • React component — displays loading bar and simulates progress
  • Redux reducer — manages loading bar's part of the store
  • (optional) Redux middleware — automatically shows and hides Loading Bar for actions with promises

View Demo: https://mironov.github.io/react-redux-loading-bar/

Github: http://github.com/mironov/react-redux-loading-bar

Download Link: https://github.com/mironov/react-redux-loading-bar/archive/master.zip

9. Material UI Image

Images are ugly until they're loaded. Materialize it with material image! It will fade in like the material image loading pattern suggests.

View Demo: https://mui.wertarbyte.com/#material-ui-image

Github: http://github.com/TeamWertarbyte/material-ui-image

Download Link: https://github.com/TeamWertarbyte/material-ui-image/archive/master.zip

10. React Lazy Load Image Component

React Component to lazy load images and other components/elements. Includes a HOC to track window scroll position to improve performance.

React Component to lazy load images and components using a HOC to track window scroll position.

View Demo: https://www.albertjuhe.com/react-lazy-load-image-component/

Github: http://github.com/Aljullu/react-lazy-load-image-component

Download Link: https://github.com/Aljullu/react-lazy-load-image-component/archive/master.zip