Skip to content

Instantly share code, notes, and snippets.

View sergiodxa's full-sized avatar

Sergio Xalambrí sergiodxa

View GitHub Profile
@sergiodxa
sergiodxa / react-query-crud.ts
Created February 10, 2021 00:28
CRUD mutations (not read) for React Query + TS
import { useMutation, UseMutationOptions } from "react-query";
import { pluralize, singularize } from "inflected";
import { generatePath } from "react-router-dom";
type Config<Input, Output, Error> = {
/**
* Any React Query option for useMutation
* @type {UseMutationOptions<Output, APIError<Error>, Input>}
*/
options?: UseMutationOptions<Output, APIError<Error>, Input>;
@sergiodxa
sergiodxa / form.tsx
Created January 10, 2021 01:21
A Form component which automatically run a React Query v2 mutation
import { useCallback, ReactNode, FormEventHandler } from "react";
import { MutationResultPair, MutateConfig, QueryStatus } from "react-query";
import * as yup from "yup";
function noop() {}
type FormProps<Data> = {
action: MutationResultPair<Data, Error, FormData, never | (() => void)>;
children(status: QueryStatus): ReactNode;
validation: yup.ObjectSchema;
@sergiodxa
sergiodxa / use-entity.ts
Created January 5, 2021 22:53
A React Query wrapper to fetch individual entities from a REST API
import { useQuery, QueryConfig } from "react-query";
type ID = string | number;
type Resource = { name: string; id: ID };
class APIClientError extends Error {}
class APIServerError extends Error {}
export async function getEntity<Entity = unknown>(
@sergiodxa
sergiodxa / til-querySelectorAll-scope.js
Created December 31, 2020 03:08
TIL: Al usar querySelector(All) desde un elemento es posible usar `:scope` para referirse a ese elemento en el selector de CSS, así podemos usar selectores como `>` para solo obtener hijos directos de nuestro elemento padre
/**
* Si tenemos este HTML
* <section id="some-section">
* <article> <h2>Article 1</h2> <article>A nested one</article> </article>
* <article> <h2>Article 2</h2> <article>A nested one</article> </article>
* <article> <h2>Article 3</h2> <article>A nested one</article> </article>
* </section>
*/
const section = document.querySelector("#some-section");
// Haciendo esto obtenemos seis artículos
@sergiodxa
sergiodxa / organized-component.tsx
Created August 9, 2020 01:12
How do I organize React components internally
function MyComponent(props) {
// refs
const $item = React.useRef();
// states
const [value, setValue] = React.useState("");
// computed
const filtered = React.useMemo(
() => props.list.filter((item) => item.includes(value)),
[props.list, value]
);
@sergiodxa
sergiodxa / react-feature-flags.js
Created October 24, 2019 17:55
React feature flags context, custom hook, hoc and render prop
import React from "react";
const FeatureFlags = React.createContext(null);
export function FeatureProvider({ features = null, children }) {
if (features === null || typeof features !== "object") {
throw new TypeError("The features prop must be an object or an array.");
}
return (
<FeatureFlags.Provider value={features}>{children}</FeatureFlags.Provider>
@sergiodxa
sergiodxa / stale-and-revalidate.js
Last active June 11, 2019 16:04
Fetch data from an API and show it in the DOM. Save the data on the Storage and use it when the user reload to immediately update the DOM while fetching new data from the API.
const URL = "https://jsonplaceholder.typicode.com/posts?_page=2";
async function getData(staleData = {}) {
const response = await fetch(URL);
const data = await response.json();
return data.reduce((posts, post) => {
return {
...posts,
[post.id]: posts.hasOwnProperty(post.id)
? { ...posts[post.id], ...post }
@sergiodxa
sergiodxa / use-nprogress.js
Created November 29, 2018 21:35
Hook to use NProgress in a Next.js application
import { useRef, useEffect } from "react";
import NProgress from "nprogress";
import Router from "next/router";
function useNProgress(showAfterMs = 300, options = {}) {
const timer = useRef(null);
function routeChangeStart() {
const { showAfterMs } = this.props;
clearTimeout(timer.current);
@sergiodxa
sergiodxa / human-readable-duration-format.js
Created September 10, 2018 21:07
Human readable duration format
const messages = {
year: { singular: 'year', plural: 'years', denominator: 365, inSeconds: 31536000 },
day: { singular: 'day', plural: 'days', denominator: 24, inSeconds: 86400 },
hour: { singular: 'hour', plural: 'hours', denominator: 60, inSeconds: 3600 },
minute: { singular: 'minute', plural: 'minutes', denominator: 60, inSeconds: 60 },
second: { singular: 'second', plural: 'seconds', inSeconds: 1 }
}
function pluralize(value, unit) {
if (value === 1) return messages[unit].singular;

Keybase proof

I hereby claim:

  • I am sergiodxa on github.
  • I am sergiodxa (https://keybase.io/sergiodxa) on keybase.
  • I have a public key ASAOxsN5DBoO1ScNStFiY44HaTdSfjGzvTnbnsamYYvjswo

To claim this, I am signing this object: