Skip to content

Instantly share code, notes, and snippets.

@kentcdodds
Created October 18, 2021 21:38
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save kentcdodds/ecec3987280c6120ba9f987c321fdabb to your computer and use it in GitHub Desktop.
Save kentcdodds/ecec3987280c6120ba9f987c321fdabb to your computer and use it in GitHub Desktop.
A real-world example of the prop getters pattern
function Cell({
value,
row: {values: user},
column: {id: propertyName},
}: {
value: string
row: {values: User}
column: {id: string}
}) {
const [isEditing, setIsEditing] = React.useState(false)
const dc = useDoubleCheck()
return isEditing ? (
propertyName === 'id' ? (
<Form
method="delete"
onSubmit={() => setIsEditing(false)}
onBlur={() => setIsEditing(false)}
onKeyUp={e => {
if (e.key === 'Escape') setIsEditing(false)
}}
>
<input type="hidden" name="id" value={user.id} />
<Button
type="submit"
variant="danger"
autoFocus
{...dc.getButtonProps()}
>
{dc.doubleCheck ? 'You sure?' : 'Delete'}
</Button>
</Form>
) : (
<Form
method="post"
onSubmit={() => setIsEditing(false)}
onBlur={() => setIsEditing(false)}
onKeyUp={e => {
if (e.key === 'Escape') setIsEditing(false)
}}
>
<input type="hidden" name="id" value={user.id} />
<input type="text" defaultValue={value} name={propertyName} autoFocus />
</Form>
)
) : (
<button className="border-none" onClick={() => setIsEditing(true)}>
{value || 'NO_VALUE'}
</button>
)
}
function useDoubleCheck() {
const [doubleCheck, setDoubleCheck] = React.useState(false)
function getButtonProps(props?: JSX.IntrinsicElements['button']) {
const onBlur: JSX.IntrinsicElements['button']['onBlur'] = () =>
setDoubleCheck(false)
const onClick: JSX.IntrinsicElements['button']['onClick'] = doubleCheck
? undefined
: e => {
e.preventDefault()
setDoubleCheck(true)
}
return {
...props,
onBlur: callAll(onBlur, props?.onBlur),
onClick: callAll(onClick, props?.onClick),
}
}
return {doubleCheck, getButtonProps}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment