Skip to content

Instantly share code, notes, and snippets.

@sibelius
Last active November 15, 2019 01:53
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save sibelius/d44c23c1b50f2edb393718b0236dbb20 to your computer and use it in GitHub Desktop.
Save sibelius/d44c23c1b50f2edb393718b0236dbb20 to your computer and use it in GitHub Desktop.
useControlledState to provide a uncontrolled and controlled api for your components
import { useState } from 'react';
export const useControlledState = <T extends any>(value: T, onChange?: (value: T) => void) => {
const [uncontrolledValue, setUncontrolledValue] = useState(value);
if (typeof onChange === 'function') {
// Controlled version
return [value, onChange];
}
// Uncontrolled version
return [uncontrolledValue, setUncontrolledValue];
};
@sibelius
Copy link
Author

tks, I was just lazy about typing properly \o/

@sibelius
Copy link
Author

there is just one problem with your typing, it should be

<T extends any>

typescript does not handle <> generics on .tsx files

@maraisr
Copy link

maraisr commented Nov 15, 2019

not true. Its not a tsx thing, it's the fact that arrow functions can't have "naked" generics. But you could also argue that it should'nt be a generic at all. Because all .value props from native inputs are strings.

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