Skip to content

Instantly share code, notes, and snippets.

@wjramos
Last active August 10, 2022 23:37
Show Gist options
  • Save wjramos/9b705f553c662845bd7e856132eeec6f to your computer and use it in GitHub Desktop.
Save wjramos/9b705f553c662845bd7e856132eeec6f to your computer and use it in GitHub Desktop.
export default (() => {
let hooks = []
let currentIndex = 0
const render = Component => {
// Run effects
const component = Component()
component.render()
// Reset hooks
currentIndex = 0
return component
}
// https://reactjs.org/docs/hooks-reference.html#useeffect
const useEffect = (callback, hookDependencies) => {
if (!hookDependencies) return
const dependencies = hooks[currentIndex]
const isUnchanged = dependencies && hookDependencies.every((dependency, i) => dependency === dependencies[i])
if (isUnchanged) return
callback()
hooks[currentIndex] = hookDependencies
currentIndex++
}
// https://reactjs.org/docs/hooks-reference.html#usestate
const useState = initialValue => {
hooks[currentIndex] = hooks[currentIndex] || initialValue
return [
hooks[currentIndex++],
newState => hooks[currentIndex] = newState,
]
}
// https://reactjs.org/docs/hooks-reference.html#useref
const useRef = initialValue => {
const [ref] = useState({ current: initialValue })
return ref
}
// https://reactjs.org/docs/hooks-reference.html#usememo
const useMemo = (getValue, hookDependencies) => {
const [value, setValue] = useState(getValue())
useEffect(
() => {
setValue(getValue())
},
hookDependencies,
)
return value
}
// https://reactjs.org/docs/hooks-reference.html#usecallback
const useCallback = (fn, hookDependencies) => {
const [callback, setCallback] = useState(fn)
useEffect(
() => {
setCallback(fn)
},
hookDependencies,
)
return callback
}
// https://reactjs.org/docs/hooks-reference.html#usereducer
const useReducer = (reducer, initialState, init) => {
const [state, setState] = useState(init?.(initialState) || initialState)
const dispatch = (action) => setState(currentState => reducer(currentState, action))
return [state, dispatch]
}
// TODO: Implement
// https://reactjs.org/docs/hooks-reference.html#useimperativehandle
const useImperativeHandle = (ref, createHandle, [deps]) => {}
// TODO: Implement
// https://reactjs.org/docs/hooks-reference.html#uselayouteffect
const useLayoutEffect = () => {}
// TODO: Implement
// https://reactjs.org/docs/hooks-reference.html#usedebugvalue
const useDebugValue = (value, format) => {}
// TODO: Implement
// https://reactjs.org/docs/hooks-reference.html#usedeferredvalue
const useDeferredValue = (value) => {}
// https://reactjs.org/docs/hooks-reference.html#usetransition
const useTransition = () => {
const [isPending, setPending] = useState(true)
const startTransition = async (fn) => {
await fn()
setPending(false)
}
return [isPending, startTransition]
}
// TODO: Implement
// https://reactjs.org/docs/hooks-reference.html#useid
const useId = () => ':unique-id'
// https://reactjs.org/docs/hooks-reference.html#usesyncexternalstore
const useSyncExternalStore = () => {}
// https://reactjs.org/docs/hooks-reference.html#useinsertioneffect
const useInsertionEffect = (didUpdate) => {}
return {
render,
useState,
useEffect,
useRef,
useMemo,
useCallback,
useReducer,
useImperativeHandle,
useLayoutEffect,
useDebugValue,
useDeferredValue,
useTransition,
useId,
useSyncExternalStore,
useInsertionEffect,
}
})()
@wjramos
Copy link
Author

wjramos commented Apr 14, 2022

Usage:

const MyComponent = () => {
  const [isThisCool, setCool] = Hooks.useState(true)
  const isCoolToggleRef = Hooks.useRef()
  const toggleCool = Hooks.useCallback(() => setCool((state) => !state), [setCool])
  const buttonText = Hooks.useMemo(() => isThisCool ? 'I think this is cool' : 'I think this is not very cool at all', [isThisCool])

  Hooks.useEffect(() => {
    isThisCool && alert('This IS cool, isn\'t it?')
  }, [isThisCool])

  return (
    <Button
      ref={isCoolToggleRef}
      onPress={toggleCool}
    >
      {buttonText}
    </Button>
  );
}

Hooks.render(MyComponent)

@wjramos
Copy link
Author

wjramos commented Apr 14, 2022

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment