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 |
---|
defaultState | boolean | default as false |
onOn | function | callback function fires when state is true |
onOff | function | callback function fires when state is false |
Return
name |
type |
description |
---|
isOn | boolean | |
toggle | function | to trigger the state |
toggleOn | function | to trigger the state to true |
toggleOff | function | to trigger the state to false |
Example
Try to open count: 0
Example (with bug)
Try to open count: 0
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>
</>
)
}