useToggleuseToggle+useEventRefuseSafeEffectuseEventControluseDebounceuseThrottleuseClickOutsideuseTabsuseDateuseDatesuseImageuseCaptureuseIntersectionObserver
react react-hook ironman30

useToggle Plus

A more advanced hook from useToggle.


LINKS

鐵人賽連結

Hook 參考來源

Example

Example (with bug)


function useToggle(props = {}) {
  const { defaultState, onOn, onOff } = props

  if (defaultState !== undefined && typeof defaultState !== "boolean") {
    throw new Error("UseToggle: defaultState should be Boolean")
  }
  const [state, setState] = useState(defaultState || false)

  const onOnEventCallback = useEventRef(onOn)
  const onOffEventCallback = useEventRef(onOff)

  const toggleOn = useCallback(() => {
    setState(true)
    onOnEventCallback()
  }, [])

  const toggleOff = useCallback(() => {
    setState(false)
    onOffEventCallback()
  }, [])

  const toggle = useCallback(() => {
    const action = state ? toggleOff : toggleOn
    action()
  }, [state])

  return { isOn: state, toggle, toggleOn, toggleOff }
}

Params

name type description
defaultStatebooleandefault as false
onOnfunctioncallback function fires when state is true
onOfffunctioncallback function fires when state is false

Return

name type description
isOnboolean
togglefunctionto trigger the state
toggleOnfunctionto trigger the state to true
toggleOfffunctionto trigger the state to false

Example

Try to open count: 0
Hello (´・ω・`)

Example (with bug)

Try to open count: 0
Hello (´・ω・`)
function useBugToggle(props = {}) {
  const { defaultState, onOn, onOff } = props

  if (defaultState !== undefined && typeof defaultState !== "boolean") {
    throw new Error("UseToggle: defaultState should be Boolean")
  }

  const [state, setState] = useState(defaultState || false)

  const toggleOn = useCallback(() => {
    setState(true)
    onOn?.()
  }, [])

  const toggleOff = useCallback(() => {
    setState(false)
    onOff?.()
  }, [])

  const toggle = useCallback(() => {
    const action = state ? toggleOff : toggleOn
    action()
  }, [state])

  return { isOn: state, toggle, toggleOn, toggleOff }
}

VIEW

function Example() {
  const [count, setCount] = useState(0)
  const { isOn, toggle, toggleOn, toggleOff } = useToggle({
    onOn: () => setCount(count + 1),
  })
  return (
    <>
      <Tag>Try to open count: {count}</Tag>
      <Flex gap={2} sx={{ "& > *": { flex: 1 } }}>
        <Button onClick={toggle}>TOGGLE</Button>
        <Button onClick={toggleOn}>ON</Button>
        <Button onClick={toggleOff}>OFF</Button>
      </Flex>
      <Fade in={isOn}>
        <StyledBox>Hello (´・ω・`)</StyledBox>
      </Fade>
    </>
  )
}