Devil  Moya

Devil Moya

1575911430

8 Practices In React that will Crash your application

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:

eslint

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>
  )
}

frogs1

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:

frogs2

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 !

#react #javascript #best practice

What is GEEK

Buddha Community

8 Practices In React that will Crash your application
Autumn  Blick

Autumn Blick

1598839687

How native is React Native? | React Native vs Native App Development

If you are undertaking a mobile app development for your start-up or enterprise, you are likely wondering whether to use React Native. As a popular development framework, React Native helps you to develop near-native mobile apps. However, you are probably also wondering how close you can get to a native app by using React Native. How native is React Native?

In the article, we discuss the similarities between native mobile development and development using React Native. We also touch upon where they differ and how to bridge the gaps. Read on.

A brief introduction to React Native

Let’s briefly set the context first. We will briefly touch upon what React Native is and how it differs from earlier hybrid frameworks.

React Native is a popular JavaScript framework that Facebook has created. You can use this open-source framework to code natively rendering Android and iOS mobile apps. You can use it to develop web apps too.

Facebook has developed React Native based on React, its JavaScript library. The first release of React Native came in March 2015. At the time of writing this article, the latest stable release of React Native is 0.62.0, and it was released in March 2020.

Although relatively new, React Native has acquired a high degree of popularity. The “Stack Overflow Developer Survey 2019” report identifies it as the 8th most loved framework. Facebook, Walmart, and Bloomberg are some of the top companies that use React Native.

The popularity of React Native comes from its advantages. Some of its advantages are as follows:

  • Performance: It delivers optimal performance.
  • Cross-platform development: You can develop both Android and iOS apps with it. The reuse of code expedites development and reduces costs.
  • UI design: React Native enables you to design simple and responsive UI for your mobile app.
  • 3rd party plugins: This framework supports 3rd party plugins.
  • Developer community: A vibrant community of developers support React Native.

Why React Native is fundamentally different from earlier hybrid frameworks

Are you wondering whether React Native is just another of those hybrid frameworks like Ionic or Cordova? It’s not! React Native is fundamentally different from these earlier hybrid frameworks.

React Native is very close to native. Consider the following aspects as described on the React Native website:

  • Access to many native platforms features: The primitives of React Native render to native platform UI. This means that your React Native app will use many native platform APIs as native apps would do.
  • Near-native user experience: React Native provides several native components, and these are platform agnostic.
  • The ease of accessing native APIs: React Native uses a declarative UI paradigm. This enables React Native to interact easily with native platform APIs since React Native wraps existing native code.

Due to these factors, React Native offers many more advantages compared to those earlier hybrid frameworks. We now review them.

#android app #frontend #ios app #mobile app development #benefits of react native #is react native good for mobile app development #native vs #pros and cons of react native #react mobile development #react native development #react native experience #react native framework #react native ios vs android #react native pros and cons #react native vs android #react native vs native #react native vs native performance #react vs native #why react native #why use react native

Annie  Emard

Annie Emard

1653075360

HAML Lint: Tool For Writing Clean and Consistent HAML

HAML-Lint

haml-lint is a tool to help keep your HAML files clean and readable. In addition to HAML-specific style and lint checks, it integrates with RuboCop to bring its powerful static analysis tools to your HAML documents.

You can run haml-lint manually from the command line, or integrate it into your SCM hooks.

Requirements

  • Ruby 2.4+
  • HAML 4.0+

Installation

gem install haml_lint

If you'd rather install haml-lint using bundler, don't require it in your Gemfile:

gem 'haml_lint', require: false

Then you can still use haml-lint from the command line, but its source code won't be auto-loaded inside your application.

Usage

Run haml-lint from the command line by passing in a directory (or multiple directories) to recursively scan:

haml-lint app/views/

You can also specify a list of files explicitly:

haml-lint app/**/*.html.haml

haml-lint will output any problems with your HAML, including the offending filename and line number.

File Encoding

haml-lint assumes all files are encoded in UTF-8.

Command Line Flags

Command Line FlagDescription
--auto-gen-configGenerate a configuration file acting as a TODO list
--auto-gen-exclude-limitNumber of failures to allow in the TODO list before the entire rule is excluded
-c/--configSpecify which configuration file to use
-e/--excludeExclude one or more files from being linted
-i/--include-linterSpecify which linters you specifically want to run
-x/--exclude-linterSpecify which linters you don't want to run
-r/--reporterSpecify which reporter you want to use to generate the output
-p/--parallelRun linters in parallel using available CPUs
--fail-fastSpecify whether to fail after the first file with lint
--fail-levelSpecify the minimum severity (warning or error) for which the lint should fail
--[no-]colorWhether to output in color
--[no-]summaryWhether to output a summary in the default reporter
--show-lintersShow all registered linters
--show-reportersDisplay available reporters
-h/--helpShow command line flag documentation
-v/--versionShow haml-lint version
-V/--verbose-versionShow haml-lint, haml, and ruby version information

Configuration

haml-lint will automatically recognize and load any file with the name .haml-lint.yml as a configuration file. It loads the configuration based on the directory haml-lint is being run from, ascending until a configuration file is found. Any configuration loaded is automatically merged with the default configuration (see config/default.yml).

Here's an example configuration file:

linters:
  ImplicitDiv:
    enabled: false
    severity: error

  LineLength:
    max: 100

All linters have an enabled option which can be true or false, which controls whether the linter is run, along with linter-specific options. The defaults are defined in config/default.yml.

Linter Options

OptionDescription
enabledIf false, this linter will never be run. This takes precedence over any other option.
includeList of files or glob patterns to scope this linter to. This narrows down any files specified via the command line.
excludeList of files or glob patterns to exclude from this linter. This excludes any files specified via the command line or already filtered via the include option.
severityThe severity of the linter. External tools consuming haml-lint output can use this to determine whether to warn or error based on the lints reported.

Global File Exclusion

The exclude global configuration option allows you to specify a list of files or glob patterns to exclude from all linters. This is useful for ignoring third-party code that you don't maintain or care to lint. You can specify a single string or a list of strings for this option.

Skipping Frontmatter

Some static blog generators such as Jekyll include leading frontmatter to the template for their own tracking purposes. haml-lint allows you to ignore these headers by specifying the skip_frontmatter option in your .haml-lint.yml configuration:

skip_frontmatter: true

Inheriting from Other Configuration Files

The inherits_from global configuration option allows you to specify an inheritance chain for a configuration file. It accepts either a scalar value of a single file name or a vector of multiple files to inherit from. The inherited files are resolved in a first in, first out order and with "last one wins" precedence. For example:

inherits_from:
  - .shared_haml-lint.yml
  - .personal_haml-lint.yml

First, the default configuration is loaded. Then the .shared_haml-lint.yml configuration is loaded, followed by .personal_haml-lint.yml. Each of these overwrite each other in the event of a collision in configuration value. Once the inheritance chain is resolved, the base configuration is loaded and applies its rules to overwrite any in the intermediate configuration.

Lastly, in order to match your RuboCop configuration style, you can also use the inherit_from directive, which is an alias for inherits_from.

Linters

» Linters Documentation

haml-lint is an opinionated tool that helps you enforce a consistent style in your HAML files. As an opinionated tool, we've had to make calls about what we think are the "best" style conventions, even when there are often reasonable arguments for more than one possible style. While all of our choices have a rational basis, we think that the opinions themselves are less important than the fact that haml-lint provides us with an automated and low-cost means of enforcing consistency.

Custom Linters

Add the following to your configuration file:

require:
  - './relative/path/to/my_first_linter.rb'
  - 'absolute/path/to/my_second_linter.rb'

The files that are referenced by this config should have the following structure:

module HamlLint
  # MyFirstLinter is the name of the linter in this example, but it can be anything
  class Linter::MyFirstLinter < Linter
    include LinterRegistry

    def visit_tag
      return unless node.tag_name == 'div'
      record_lint(node, "You're not allowed divs!")
    end
  end
end

For more information on the different types on HAML node, please look through the HAML parser code: https://github.com/haml/haml/blob/master/lib/haml/parser.rb

Keep in mind that by default your linter will be disabled by default. So you will need to enable it in your configuration file to have it run.

Disabling Linters within Source Code

One or more individual linters can be disabled locally in a file by adding a directive comment. These comments look like the following:

-# haml-lint:disable AltText, LineLength
[...]
-# haml-lint:enable AltText, LineLength

You can disable all linters for a section with the following:

-# haml-lint:disable all

Directive Scope

A directive will disable the given linters for the scope of the block. This scope is inherited by child elements and sibling elements that come after the comment. For example:

-# haml-lint:disable AltText
#content
  %img#will-not-show-lint-1{ src: "will-not-show-lint-1.png" }
  -# haml-lint:enable AltText
  %img#will-show-lint-1{ src: "will-show-lint-1.png" }
  .sidebar
    %img#will-show-lint-2{ src: "will-show-lint-2.png" }
%img#will-not-show-lint-2{ src: "will-not-show-lint-2.png" }

The #will-not-show-lint-1 image on line 2 will not raise an AltText lint because of the directive on line 1. Since that directive is at the top level of the tree, it applies everywhere.

However, on line 4, the directive enables the AltText linter for the remainder of the #content element's content. This means that the #will-show-lint-1 image on line 5 will raise an AltText lint because it is a sibling of the enabling directive that appears later in the #content element. Likewise, the #will-show-lint-2 image on line 7 will raise an AltText lint because it is a child of a sibling of the enabling directive.

Lastly, the #will-not-show-lint-2 image on line 8 will not raise an AltText lint because the enabling directive on line 4 exists in a separate element and is not a sibling of the it.

Directive Precedence

If there are multiple directives for the same linter in an element, the last directive wins. For example:

-# haml-lint:enable AltText
%p Hello, world!
-# haml-lint:disable AltText
%img#will-not-show-lint{ src: "will-not-show-lint.png" }

There are two conflicting directives for the AltText linter. The first one enables it, but the second one disables it. Since the disable directive came later, the #will-not-show-lint element will not raise an AltText lint.

You can use this functionality to selectively enable directives within a file by first using the haml-lint:disable all directive to disable all linters in the file, then selectively using haml-lint:enable to enable linters one at a time.

Onboarding Onto a Preexisting Project

Adding a new linter into a project that wasn't previously using one can be a daunting task. To help ease the pain of starting to use Haml-Lint, you can generate a configuration file that will exclude all linters from reporting lint in files that currently have lint. This gives you something similar to a to-do list where the violations that you had when you started using Haml-Lint are listed for you to whittle away, but ensuring that any views you create going forward are properly linted.

To use this functionality, call Haml-Lint like:

haml-lint --auto-gen-config

This will generate a .haml-lint_todo.yml file that contains all existing lint as exclusions. You can then add inherits_from: .haml-lint_todo.yml to your .haml-lint.yml configuration file to ensure these exclusions are used whenever you call haml-lint.

By default, any rules with more than 15 violations will be disabled in the todo-file. You can increase this limit with the auto-gen-exclude-limit option:

haml-lint --auto-gen-config --auto-gen-exclude-limit 100

Editor Integration

Vim

If you use vim, you can have haml-lint automatically run against your HAML files after saving by using the Syntastic plugin. If you already have the plugin, just add let g:syntastic_haml_checkers = ['haml_lint'] to your .vimrc.

Vim 8 / Neovim

If you use vim 8+ or Neovim, you can have haml-lint automatically run against your HAML files as you type by using the Asynchronous Lint Engine (ALE) plugin. ALE will automatically lint your HAML files if it detects haml-lint in your PATH.

Sublime Text 3

If you use SublimeLinter 3 with Sublime Text 3 you can install the SublimeLinter-haml-lint plugin using Package Control.

Atom

If you use atom, you can install the linter-haml plugin.

TextMate 2

If you use TextMate 2, you can install the Haml-Lint.tmbundle bundle.

Visual Studio Code

If you use Visual Studio Code, you can install the Haml Lint extension

Git Integration

If you'd like to integrate haml-lint into your Git workflow, check out our Git hook manager, overcommit.

Rake Integration

To execute haml-lint via a Rake task, make sure you have rake included in your gem path (e.g. via Gemfile) add the following to your Rakefile:

require 'haml_lint/rake_task'

HamlLint::RakeTask.new

By default, when you execute rake haml_lint, the above configuration is equivalent to running haml-lint ., which will lint all .haml files in the current directory and its descendants.

You can customize your task by writing:

require 'haml_lint/rake_task'

HamlLint::RakeTask.new do |t|
  t.config = 'custom/config.yml'
  t.files = ['app/views', 'custom/*.haml']
  t.quiet = true # Don't display output from haml-lint to STDOUT
end

You can also use this custom configuration with a set of files specified via the command line:

# Single quotes prevent shell glob expansion
rake 'haml_lint[app/views, custom/*.haml]'

Files specified in this manner take precedence over the task's files attribute.

Documentation

Code documentation is generated with YARD and hosted by RubyDoc.info.

Contributing

We love getting feedback with or without pull requests. If you do add a new feature, please add tests so that we can avoid breaking it in the future.

Speaking of tests, we use Appraisal to test against both HAML 4 and 5. We use rspec to write our tests. To run the test suite, execute the following from the root directory of the repository:

appraisal bundle install
appraisal bundle exec rspec

Community

All major discussion surrounding HAML-Lint happens on the GitHub issues page.

Changelog

If you're interested in seeing the changes and bug fixes between each version of haml-lint, read the HAML-Lint Changelog.

Author: sds
Source Code: https://github.com/sds/haml-lint
License: MIT license

#haml #lint 

Mathew Rini

1615544450

How to Select and Hire the Best React JS and React Native Developers?

Since March 2020 reached 556 million monthly downloads have increased, It shows that React JS has been steadily growing. React.js also provides a desirable amount of pliancy and efficiency for developing innovative solutions with interactive user interfaces. It’s no surprise that an increasing number of businesses are adopting this technology. How do you select and recruit React.js developers who will propel your project forward? How much does a React developer make? We’ll bring you here all the details you need.

What is React.js?

Facebook built and maintains React.js, an open-source JavaScript library for designing development tools. React.js is used to create single-page applications (SPAs) that can be used in conjunction with React Native to develop native cross-platform apps.

React vs React Native

  • React Native is a platform that uses a collection of mobile-specific components provided by the React kit, while React.js is a JavaScript-based library.
  • React.js and React Native have similar syntax and workflows, but their implementation is quite different.
  • React Native is designed to create native mobile apps that are distinct from those created in Objective-C or Java. React, on the other hand, can be used to develop web apps, hybrid and mobile & desktop applications.
  • React Native, in essence, takes the same conceptual UI cornerstones as standard iOS and Android apps and assembles them using React.js syntax to create a rich mobile experience.

What is the Average React Developer Salary?

In the United States, the average React developer salary is $94,205 a year, or $30-$48 per hour, This is one of the highest among JavaScript developers. The starting salary for junior React.js developers is $60,510 per year, rising to $112,480 for senior roles.

* React.js Developer Salary by Country

  • United States- $120,000
  • Canada - $110,000
  • United Kingdom - $71,820
  • The Netherlands $49,095
  • Spain - $35,423.00
  • France - $44,284
  • Ukraine - $28,990
  • India - $9,843
  • Sweden - $55,173
  • Singapore - $43,801

In context of software developer wage rates, the United States continues to lead. In high-tech cities like San Francisco and New York, average React developer salaries will hit $98K and $114per year, overall.

However, the need for React.js and React Native developer is outpacing local labour markets. As a result, many businesses have difficulty locating and recruiting them locally.

It’s no surprise that for US and European companies looking for professional and budget engineers, offshore regions like India are becoming especially interesting. This area has a large number of app development companies, a good rate with quality, and a good pool of React.js front-end developers.

As per Linkedin, the country’s IT industry employs over a million React specialists. Furthermore, for the same or less money than hiring a React.js programmer locally, you may recruit someone with much expertise and a broader technical stack.

How to Hire React.js Developers?

  • Conduct thorough candidate research, including portfolios and areas of expertise.
  • Before you sit down with your interviewing panel, do some homework.
  • Examine the final outcome and hire the ideal candidate.

Why is React.js Popular?

React is a very strong framework. React.js makes use of a powerful synchronization method known as Virtual DOM, which compares the current page architecture to the expected page architecture and updates the appropriate components as long as the user input.

React is scalable. it utilises a single language, For server-client side, and mobile platform.

React is steady.React.js is completely adaptable, which means it seldom, if ever, updates the user interface. This enables legacy projects to be updated to the most new edition of React.js without having to change the codebase or make a few small changes.

React is adaptable. It can be conveniently paired with various state administrators (e.g., Redux, Flux, Alt or Reflux) and can be used to implement a number of architectural patterns.

Is there a market for React.js programmers?
The need for React.js developers is rising at an unparalleled rate. React.js is currently used by over one million websites around the world. React is used by Fortune 400+ businesses and popular companies such as Facebook, Twitter, Glassdoor and Cloudflare.

Final thoughts:

As you’ve seen, locating and Hire React js Developer and Hire React Native developer is a difficult challenge. You will have less challenges selecting the correct fit for your projects if you identify growing offshore locations (e.g. India) and take into consideration the details above.

If you want to make this process easier, You can visit our website for more, or else to write a email, we’ll help you to finding top rated React.js and React Native developers easier and with strives to create this operation

#hire-react-js-developer #hire-react-native-developer #react #react-native #react-js #hire-react-js-programmer

Devil  Moya

Devil Moya

1575911430

8 Practices In React that will Crash your application

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:

eslint

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>
  )
}

frogs1

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:

frogs2

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 !

#react #javascript #best practice

Franz  Becker

Franz Becker

1651604400

React Starter Kit: Build Web Apps with React, Relay and GraphQL.

React Starter Kit — "isomorphic" web app boilerplate   

React Starter Kit is an opinionated boilerplate for web development built on top of Node.js, Express, GraphQL and React, containing modern web development tools such as Webpack, Babel and Browsersync. Helping you to stay productive following the best practices. A solid starting point for both professionals and newcomers to the industry.

See getting started guide, demo, docs, roadmap  |  Join #react-starter-kit chat room on Gitter  |  Visit our sponsors:

 

Hiring

Getting Started

Customization

The master branch of React Starter Kit doesn't include a Flux implementation or any other advanced integrations. Nevertheless, we have some integrations available to you in feature branches that you can use either as a reference or merge into your project:

You can see status of most reasonable merge combination as PRs labeled as TRACKING

If you think that any of these features should be on master, or vice versa, some features should removed from the master branch, please let us know. We love your feedback!

Comparison

 

React Starter Kit

React Static Boilerplate

ASP.NET Core Starter Kit

App typeIsomorphic (universal)Single-page applicationSingle-page application
Frontend
LanguageJavaScript (ES2015+, JSX)JavaScript (ES2015+, JSX)JavaScript (ES2015+, JSX)
LibrariesReact, History, Universal RouterReact, History, ReduxReact, History, Redux
RoutesImperative (functional)DeclarativeDeclarative, cross-stack
Backend
LanguageJavaScript (ES2015+, JSX)n/aC#, F#
LibrariesNode.js, Express, Sequelize,
GraphQL
n/aASP.NET Core, EF Core,
ASP.NET Identity
SSRYesn/an/a
Data APIGraphQLn/aWeb API

Backers

♥ React Starter Kit? Help us keep it alive by donating funds to cover project expenses via OpenCollective or Bountysource!

lehneres Tarkan Anlar Morten Olsen Adam David Ernst Zane Hitchcox  

How to Contribute

Anyone and everyone is welcome to contribute to this project. The best way to start is by checking our open issues, submit a new issue or feature request, participate in discussions, upvote or downvote the issues you like or dislike, send pull requests.

Learn More

Related Projects

  • GraphQL Starter Kit — Boilerplate for building data APIs with Node.js, JavaScript (via Babel) and GraphQL
  • Membership Database — SQL schema boilerplate for user accounts, profiles, roles, and auth claims
  • Babel Starter Kit — Boilerplate for authoring JavaScript/React.js libraries

Support

License

Copyright © 2014-present Kriasoft, LLC. This source code is licensed under the MIT license found in the LICENSE.txt file. The documentation to the project is licensed under the CC BY-SA 4.0 license.


Author: kriasoft
Source Code: https://github.com/kriasoft/react-starter-kit
License: MIT License

#graphql #react