Skip to content

Instantly share code, notes, and snippets.

View tjinlag's full-sized avatar

Tín Nguyễn tjinlag

View GitHub Profile
@tjinlag
tjinlag / shuffleItems.js
Created March 24, 2024 09:57
Shuffle an array
const shuffleItems = (items) => {
return items.map(item => ({ sort: Math.random(), value: item }))
.sort((item1, item2) => item1.sort - item2.sort)
.map(item => item.value);
}
shuffleItems([1,2,3,4,5,6]);
shuffleItems([1,2,3,4,5,6,6,8,10,12]);
@tjinlag
tjinlag / fetch.js
Created April 17, 2023 15:59
Simplified Implementation of window.fetch
function fetch(url, options) {
// create a new Promise object
return new Promise((resolve, reject) => {
// create a new XMLHttpRequest object
const xhr = new XMLHttpRequest();
// handle the response from the server
xhr.onload = () => {
const response = new Response(xhr.responseText, {
status: xhr.status,
@tjinlag
tjinlag / useOnlineStatus.js
Created April 11, 2023 10:46
React Custom Hook: useOnlineStatus
import { useState } from "react"
import useEventListener from "./useEventListener"
export default function useOnlineStatus() {
const [online, setOnline] = useState(navigator.onLine)
useEventListener("online", () => setOnline(navigator.onLine))
useEventListener("offline", () => setOnline(navigator.onLine))
return online
@tjinlag
tjinlag / useSize.js
Created April 11, 2023 10:20
React Custom Hook: useSize
import { useState, useEffect } from "react"
export default function useSize(ref) {
const [size, setSize] = useState({})
useEffect(() => {
if (ref.current == null) return
const observer = new ResizeObserver(([entry]) => setSize(entry.contentRect))
observer.observe(ref.current)
return () => observer.disconnect()
@tjinlag
tjinlag / useStateWithValidation.js
Created April 11, 2023 10:16
React Custom Hook: useStateWithValidation
import { useState, useCallback } from "react"
export default function useStateWithValidation(validationFunc, initialValue) {
const [state, setState] = useState(initialValue)
const [isValid, setIsValid] = useState(() => validationFunc(state))
const onChange = useCallback(
nextState => {
const value =
typeof nextState === "function" ? nextState(state) : nextState
@tjinlag
tjinlag / useGeolocation.js
Created April 11, 2023 10:13
React Custom Hook: useGeolocation
import { useState, useEffect } from "react"
export default function useGeolocation(options) {
const [loading, setLoading] = useState(true)
const [error, setError] = useState()
const [data, setData] = useState({})
useEffect(() => {
const successHandler = e => {
setLoading(false)
@tjinlag
tjinlag / useWindowSize.js
Created April 9, 2023 12:21
React Custom Hook: useWindowSize
import { useState } from "react"
import useEventListener from "./useEventListener"
export default function useWindowSize() {
const [windowSize, setWindowSize] = useState({
width: window.innerWidth,
height: window.innerHeight,
})
useEventListener("resize", () => {
@tjinlag
tjinlag / useOnScreen.js
Created April 9, 2023 12:20
React Custom Hook: useOnScreen
import { useEffect, useState } from "react"
export default function useOnScreen(ref, rootMargin = "0px") {
const [isVisible, setIsVisible] = useState(false)
useEffect(() => {
if (ref.current == null) return
const observer = new IntersectionObserver(
([entry]) => setIsVisible(entry.isIntersecting),
{ rootMargin }
@tjinlag
tjinlag / useEventListener.js
Created April 9, 2023 12:19
React Custom Hook: useEventListener
import { useEffect, useRef } from "react"
export default function useEventListener(
eventType,
callback,
element = window
) {
const callbackRef = useRef(callback)
useEffect(() => {
@tjinlag
tjinlag / useScript.js
Created April 9, 2023 12:10
React Custom Hook: useScript
import useAsync from "./useAsync"
export default function useScript(url) {
return useAsync(() => {
const script = document.createElement("script")
script.src = url
script.async = true
return new Promise((resolve, reject) => {
script.addEventListener("load", resolve)