My Code Docs

My Code Docs

  • Docs
  • Projects
  • Components
  • Help

›React

Javascript

  • Promises and Asnyc/Await
  • Local Storage
  • Firebase
  • JS Language Basics
  • JS Array Functions
  • Keyboard and Mouse Input
  • ES6 Cheatsheet
  • ESLint Setup
  • Data Structures
  • Naming Conventions
  • Javascript Resources
  • Javascript Snippets
  • npm Module Creation

Node

  • Node JS Basics
  • Server Config and SSH

NextJS

  • NextJS Basics

JS/React Libs

  • Lodash Library
  • Axios
  • Ramda
  • Moment JS
  • Overmind
  • Redux Forms npm Module
  • React Beautiful DnD
  • Ant Design
  • Zustand State Managment

React

  • React Basics
  • React Hooks
  • React With Classes
  • Reach Router
  • React Router
  • React Components

Redux

  • Redux in React
  • My Redux Pattern
  • Redux with React (First Doc)
  • Simple Redux Package

ReactNative

  • React Native
  • React Navigation V5
  • React Navigation V4

HTMLCSS

  • HTML and CSS Snippets
  • Tailwind CSS

Electron

  • Electron React Boiler
  • Electron Basics
  • Electron Packaging
  • Electron Tooling

React Components

react-error-boundary

React Error Boundary

Kent Dodd's Article

Wrapper around react's Error Boundary concept.

React Query ✅

React Query

Hooks for fetching, caching and updating asynchronous data in React

FocusManager

Sometimes the onBlur event on a single div or component isn't what you want. Instead, you only want to perform a blur when focus leaves a group of HTML tags.

This article helped me build the FocusManager component. Focus and Blur in Composite Widget

FocusManger.js

import React, { useState, useRef, useEffect } from "react";

const FocusManager = ({ handleBlur, children }) => {
  let [isManagingFocus, setIsManagingFocus] = useState(true);
  let timeoutIdRef = useRef();

  const _onBlur = () => {
    timeoutIdRef.current = setTimeout(() => {
      if (isManagingFocus) {
        setIsManagingFocus(false);
      }
    }, 0);
  };
  const _onFocus = () => {
    clearTimeout(timeoutIdRef.current);
    if (!isManagingFocus) {
      setIsManagingFocus(true);
    }
  };
  useEffect(() => {
    if (isManagingFocus) {
      console.log("managing focus");
    } else {
      console.log("NOT managing focus");
      handleBlur();
    }
  }, [isManagingFocus, handleBlur]);
  return (
    <div onBlur={_onBlur} onFocus={_onFocus}>
      {children}
    </div>
  );
};

export default FocusManager;

Obviously, take out the console.log statements. Just there so you can see when the events are firing.

Currently, I'm only accepting an handleBlur function that gets called when we lose focus. If needed, you could also accept a handleFocus function if needed.

From linked article

This behavior is achieved by waiting a “tick” on a blur event before toggling the isManagingFocus state to false. By a tick, I mean the next processing cycle in the main thread. We an wait a tick by using setTimeout to delay the state setting. The blur and focus events will happen in the same tick (under normal circumstances), allowing the component to cancel its reaction to the blur event if a focus event occurs in the next moment and clears the timeout. If no focus event from an element within the grid occurs (if the user has traversed out of the grid component), then the blur event will be processed in the next tick and the grid component will toggle isManagingFocus to false.

Any time we use setTimeout/clearTimeout to manage order of operations, it feels icky. I freely admit this. It seems like a hack and admittedly this approach is that. But the DOM gives us scant tools to respond to focus and blur events. We’re often left with timing hacks and interpreting secondary effects to understand where focus is on the page and where it’s going to next.

react-dates from air bnb

react-dates

Example usage of a SingleDatePicker and DateRangePicker

import 'react-dates/initialize';
import { SingleDatePicker } from 'react-dates';
import 'react-dates/lib/css/_datepicker.css';

class aComponent extends React.Component {
  onDatesChange = ({startDate, endDate}) => {
    this.props.dispatch(setStartDate(startDate));
    this.props.dispatch(setEndDate(endDate));
  }
  onFocusChange = (calendarFocused) => {
    this.setState(() => ({ calendarFocused }))
  }
render() {  
    <SingleDatePicker
    date={this.state.createdAt}
    onDateChange={this.onDateChange}
    focused={this.state.calendarFocused}
    onFocusChange={this.onFocusChange}
    numberOfMonths={1}
    isOutsideRange={(day) => false}
    />

    <DateRangePicker 
    startDate={this.props.filters.startDate}
    endDate={this.props.filters.endDate}
    onDatesChange={this.onDatesChange}
    focusedInput={this.state.calendarFocused}
    onFocusChange={this.onFocusChange}
    numberOfMonths={1}
    isOutsideRange={() => false}
    showClearDates
    />
  }
}

React Select

Drop down list box.

To install:

$ yarn add react-select@next

Here is the format for a single select drop down box:

import Select from 'react-select'; 

const Component = (props) => {
  const filterOptions = [{value: 'date', label:'Date'}, {value: 'amount', label: 'Amount'}];
  
  return (<Select options={filterOptions} 
    defaultValue={filterOptions[0]}
    styles={{control: styles => ({ ...styles, minWidth: '150px' })}}
    value={filterOptions.find((filter) => filter.value === this.props.filters.sortBy)}
    onChange={(e) => {
        if (e.value === 'date') {
            this.props.dispatch(sortByDate());
        } else {
            this.props.dispatch(sortByAmount());
        }
      }
    }
  />)
}

First, you pass the options as an array of objects with a value and label property.

If this is going to be a select list that always has a value, meaning you don't null it out, then you can set a defaultValue. But the default value must be in the form of an object with a value and label property.

Same deal with the value property. You must send an object with a value and label property.

onChange

the onChange event gets an object with a value and label property. In the example above, I'm checking what the value is and dispatching a redux action based on the selected value.

If the Select component is set to be clearable isClearable option set to true, then the a null is passed instead of an object. So, if you have a clearable select list, you will need to check if the passed value, e in this case, you must check to see if it is null:

<Select options={carFilterOptions} 
    placeholder="Car Filter..."
    isClearable={true}
    styles={{control: styles => ({ ...styles, minWidth: '150px' })}}
    value={carFilterOptions.find((filter) => filter.value === this.props.filters.carIdFilter)}
    onChange={(e) => {
          console.log(e)
          let carFilter = e ? e.value : ''
          this.props.dispatch(setCarFilter(carFilter));
    }}
/>

I used to put a blank in the select list to allow the list to be "cleared", but this is cleaner.

← React RouterRedux in React →
  • react-error-boundary
  • React Query ✅
  • FocusManager
  • react-dates from air bnb
  • React Select
    • onChange
My Code Docs
Docs
Getting Started (or other categories)Guides (or other categories)API Reference (or other categories)
Community
User ShowcaseStack OverflowProject ChatTwitter
More
BlogGitHubStar
Facebook Open Source
Copyright © 2020 McCoidCo