Skip to content

Instantly share code, notes, and snippets.

@jquense
jquense / gist:051207cee99ec7c643a5
Created November 13, 2014 19:20
join classes
function joinClasses(){
var args = [].slice.call(arguments, 0)
return args.reduce(function(current, next){
if(!current) return next
if( next) return (current ? current + " " : "") + next
})
}
@jquense
jquense / Observable.ts
Created December 5, 2022 16:48
tiny observable implementation
export interface Subscription {
readonly closed: boolean;
unsubscribe: () => void;
}
export interface Observer<T> {
closed: boolean;
error: (error: any) => void;
complete: () => void;
next: (value: T) => void;
@jquense
jquense / 0. intro.md
Last active September 24, 2022 05:10
Alternative ways to define react Components

The 0.13.0 improvements to React Components are often framed as "es6 classes" but being able to use the new class syntax isn't really the big change. The main thing of note in 0.13 is that React Components are no longer special objects that need to be created using a specific method (createClass()). One of the benefits of this change is that you can use the es6 class syntax, but also tons of other patterns work as well!

Below are a few examples creating React components that all work as expected using a bunch of JS object creation patterns (https://github.com/getify/You-Dont-Know-JS/blob/master/this%20&amp;%20object%20prototypes/ch4.md#mixins). All of the examples are of stateful components, and so need to delegate to React.Component for setState(), but if you have stateless components each patterns tends to get even simpler. The one major caveat with react components is that you need to assign props and context to the component instance otherwise the component will be static. The reason is

const { utils } = require('react-docgen');
const { default: resolveHOC } = require('react-docgen/dist/utils/resolveHOC');
const {
default: resolveToModule,
} = require('react-docgen/dist/utils/resolveToModule');
module.exports = ({ moduleName = 'styled-components' } = {}) => {
const isStyledExpression = (tagPath, t) =>
(t.CallExpression.check(tagPath.node) &&
tagPath.get('callee').node.name === 'styled') ||
@jquense
jquense / ts-workspaces-doctor.js
Created November 12, 2019 14:34
Configure a yarn workspaces to use project references and paths
/* eslint-disable no-param-reassign */
const { promises: fs, readFileSync } = require('fs');
const path = require('path');
const prettier = require('prettier');
const { parse, stringify } = require('comment-json');
const getWorkspaces = require('get-workspaces').default;
const findWorkspacesRoot = require('find-workspaces-root').default;
const safeRequire = m => {
function useEventCallback(fn) {
const ref = useRef(fn)
useLayoutEffect(() => {
ref.current = fn;
}, [fn]);
return useCallback(() => {
const fn = ref.current;
return fn();
@jquense
jquense / createStore.js
Created November 1, 2018 18:39
redux react hooks
import React, { useReducer, useContext, useMemo } from 'react'
import get from 'lodash/get'
import invariant from 'invariant'
const INIT = {
type: `INIT${Math.random()
.toString(36)
.substring(7)
.split('')
.join('.')}`,
@jquense
jquense / MainModulesPlugin.js
Created February 16, 2018 17:15
Main Module plugin webpack, concord
const concord = require('enhanced-resolve/lib/concord');
const getInnerRequest = require('enhanced-resolve/lib/getInnerRequest');
const createInnerCallback = require('enhanced-resolve/lib//createInnerCallback');
const defaultConfig = {
'./lib/**': './src/**',
};
function normalizeCondition(condition) {
let normalized = [].concat(condition);
@jquense
jquense / ScrollSpy.js
Created March 24, 2016 19:57
React ScrollSpy
import React, { PropTypes } from 'react';
import { findDOMNode } from 'react-dom'
import getOffset from 'dom-helpers/query/offset';
let ScrollSpy = React.createClass({
childContextTypes: {
$scrollSpy: PropTypes.shape({
anchor: PropTypes.func,
activeTarget: PropTypes.string
})
@jquense
jquense / routing.js
Created September 14, 2015 04:56
React router with areas and names
import React from 'react';
import { Router as BaseRouter } from 'react-router';
import { getParamNames, formatPattern } from 'react-router/lib/PatternUtils';
import { createRoutes } from 'react-router/lib/RouteUtils'
import createBrowserHistory from 'history/lib/createBrowserHistory';
import useBeforeUnload from 'history/lib/useBeforeUnload';
import invariant from 'app/utils/invariant';
import { each, pick, omit, sortBy } from 'lodash';
const EMPTY_AREA = '@@none';