Fix useStoredState when undefined is returned.

master
Auri 2022-02-10 15:00:26 -08:00
parent d246af237e
commit 8c042e7bed
7 changed files with 168 additions and 203 deletions

View File

@ -1,168 +0,0 @@
/*
👋 Hi! This file was autogenerated by tslint-to-eslint-config.
https://github.com/typescript-eslint/tslint-to-eslint-config
It represents the closest reasonable ESLint configuration to this
project's original TSLint configuration.
We recommend eventually switching this configuration to extend from
the recommended rulesets in typescript-eslint.
https://github.com/typescript-eslint/tslint-to-eslint-config/blob/master/docs/FAQs.md
Happy linting! 💖
*/
module.exports = {
"env": {
"browser": true
},
"extends": [
],
"parser": "@typescript-eslint/parser",
"parserOptions": {
"project": "tsconfig.json",
"sourceType": "module"
},
"plugins": [
"@typescript-eslint",
"eslint-plugin-jsdoc"
],
"rules": {
"@typescript-eslint/dot-notation": "error",
"@typescript-eslint/indent": [
"error",
"tab",
{
"CallExpression": {
"arguments": 1
},
"FunctionDeclaration": {
"parameters": 1
},
"FunctionExpression": {
"parameters": 1
}
}
],
"@typescript-eslint/member-delimiter-style": [
"error",
{
"multiline": {
"delimiter": "semi",
"requireLast": true
},
"singleline": {
"delimiter": "semi",
"requireLast": false
}
}
],
"@typescript-eslint/member-ordering": "error",
"@typescript-eslint/no-empty-function": "error",
"@typescript-eslint/no-explicit-any": "off",
"@typescript-eslint/no-parameter-properties": "off",
"@typescript-eslint/no-require-imports": "off",
"@typescript-eslint/no-unused-expressions": "error",
"@typescript-eslint/no-use-before-define": "error",
"@typescript-eslint/no-var-requires": "off",
"@typescript-eslint/prefer-namespace-keyword": "error",
"@typescript-eslint/quotes": [
"error",
"single"
],
"@typescript-eslint/semi": [
"error",
"always"
],
"@typescript-eslint/type-annotation-spacing": "error",
"brace-style": [
"error",
"stroustrup",
{ "allowSingleLine": true }
],
"comma-dangle": "error",
"curly": "off",
"default-case": "error",
"eol-last": "error",
"eqeqeq": [
"error",
"smart"
],
"guard-for-in": "error",
"id-blacklist": [
"error",
"any",
"Number",
"number",
"String",
"string",
"Boolean",
"boolean",
"Undefined",
"undefined"
],
"id-match": "error",
"jsdoc/check-alignment": "error",
"jsdoc/check-indentation": "error",
"jsdoc/newline-after-description": "error",
"max-len": [
"error", {
"code": 150
}
],
"no-bitwise": "error",
"no-caller": "error",
"no-console": [
"error",
{
"allow": [
"log",
"dirxml",
"warn",
"error",
"dir",
"timeLog",
"assert",
"clear",
"count",
"countReset",
"group",
"groupCollapsed",
"groupEnd",
"table",
"Console",
"markTimeline",
"profile",
"profileEnd",
"timeline",
"timelineEnd",
"timeStamp",
"context"
]
}
],
"no-debugger": "error",
"no-empty": "error",
"no-eval": "error",
"no-fallthrough": "error",
"no-new-wrappers": "error",
"no-redeclare": "off",
"@typescript-eslint/no-redeclare": ["error"],
"no-trailing-spaces": [
"error", {
"skipBlankLines": true
}
],
"no-unused-labels": "error",
"no-var": "error",
"radix": "error",
"spaced-comment": [
"error",
"always",
{
"markers": [
"/"
]
}
]
}
};

107
.eslintrc.json Normal file
View File

@ -0,0 +1,107 @@
{
"root": true,
"parser": "@typescript-eslint/parser",
"extends": [
"eslint:recommended",
"plugin:@typescript-eslint/recommended",
"prettier"
],
"plugins": [
"@typescript-eslint",
"react",
"react-hooks"
],
"settings": {
"react": {
"pragma": "h",
"version": "16.0"
}
},
"rules": {
// Typescript Rules
"@typescript-eslint/explicit-module-boundary-types": 0,
"@typescript-eslint/no-useless-constructor": 1,
"@typescript-eslint/no-redeclare": 2,
"@typescript-eslint/no-duplicate-imports": 2,
"@typescript-eslint/no-unused-vars": [ 1, { "argsIgnorePattern": "^_" } ],
"@typescript-eslint/no-non-null-assertion": 0, // TODO: Enable this rule
"@typescript-eslint/no-explicit-any": 0, // TODO: Enable this rule
// General Rules
"prefer-const": 1,
"constructor-super": 2,
"no-caller": 2,
"no-const-assign": 2,
"no-dupe-class-members": 2,
"no-dupe-keys": 2,
"no-else-return": 1,
"no-empty-pattern": 0,
"no-empty": 0,
"no-extra-parens": 0,
"no-iterator": 2,
"no-lonely-if": 2,
"no-mixed-spaces-and-tabs": [ 1, "smart-tabs" ],
"no-multi-str": 1,
"no-new-wrappers": 2,
"no-proto": 2,
"no-shadow-restricted-names": 2,
"no-shadow": 0,
"no-spaced-func": 2,
"no-this-before-super": 2,
"no-undef-init": 2,
"no-unneeded-ternary": 2,
"no-useless-call": 1,
"no-useless-computed-key": 1,
"no-useless-concat": 1,
"no-useless-escape": 1,
"no-useless-rename": 1,
"no-var": 1,
"eqeqeq": 2,
"strict": [ 2, "never" ],
"object-curly-spacing": [ 0, "always" ],
"rest-spread-spacing": 0,
"space-before-function-paren": [ 0, "always" ],
"space-in-parens": [ 0, "never" ],
"object-shorthand": 1,
"prefer-rest-params": 1,
"prefer-spread": 1,
"prefer-template": 1,
"radix": 2,
"unicode-bom": 2,
"valid-jsdoc": 0,
"no-fallthrough": 2,
"prefer-arrow-callback": [ 2, { "allowNamedFunctions": true }],
// Preact Rules
"react/no-deprecated": 2,
"react/react-in-jsx-scope": 0,
"react/display-name": [ 1, { "ignoreTranspilerName": false } ],
"react/jsx-no-bind": [ 1, {
"ignoreRefs": true,
"allowFunctions": true,
"allowArrowFunctions": true
} ],
"react/jsx-no-comment-textnodes": 2,
"react/jsx-no-duplicate-props": 2,
"react/jsx-no-target-blank": 2,
"react/jsx-no-undef": 2,
"react/jsx-uses-react": 2,
"react/jsx-uses-vars": 2,
"react/jsx-key": [ 2, { "checkFragmentShorthand": true } ],
"react/self-closing-comp": 2,
"react/prefer-es6-class": 2,
"react/prefer-stateless-function": 1,
"react/require-render-return": 2,
"react/no-did-mount-set-state": 2,
"react/no-did-update-set-state": 2,
"react/no-find-dom-node": 2,
"react/no-is-mounted": 2,
"react/no-string-refs": 2,
"react-hooks/rules-of-hooks": 2,
"react-hooks/exhaustive-deps": 1
}
}

10
.prettierrc Normal file
View File

@ -0,0 +1,10 @@
{
"tabWidth": 2,
"useTabs": true,
"printWidth": 90,
"singleQuote": true,
"jsxSingleQuote": true,
"quoteProps": "consistent",
"bracketSpacing": true,
"bracketSameLine": true
}

2
dist/package.json vendored
View File

@ -1,5 +1,5 @@
{
"version": "0.2.0",
"version": "0.2.1",
"name": "vibin-hooks",
"author": "Auri <me@auri.xyz>",
"description": "Absolutely vibin' hooks for (P)React.",

View File

@ -1,5 +1,5 @@
{
"version": "0.2.0",
"version": "0.2.1",
"private": "true",
"name": "vibin-hooks-dev",
"author": "Auri <me@auri.xyz>",

View File

@ -15,7 +15,12 @@ export default function useStoredState<T>(def: T | (() => T), key: string): [
const [ value, setValue ] = useState<T>(() => {
const stored = window.localStorage.getItem(key);
return stored !== null ? JSON.parse(stored) : def;
try {
return stored !== null && stored !== undefined ? JSON.parse(stored) : def;
} catch (e) {
console.warn('StoredState error:' + e);
return def;
}
});
useEffect(() => window.localStorage.setItem(key, JSON.stringify(value)), [ key, value ]);

View File

@ -14,49 +14,60 @@ export default function() {
entry: { main: './src/test/Main.tsx' },
output: { path: resolve(__dirname, 'build') },
resolve: {
extensions: [ '.ts', '.tsx', '.js', '.jsx' ],
extensions: ['.ts', '.tsx', '.js', '.jsx'],
},
plugins: [
new ForkTsCheckerPlugin({
typescript: { configFile: resolve(__dirname, 'tsconfig.json'), },
typescript: { configFile: resolve(__dirname, 'tsconfig.json') },
eslint: {
files: './**/*.{ts,tsx,js,jsx}',
options: {
configFile: resolve(__dirname, '.eslintrc.js'),
configFile: resolve(__dirname, '.eslintrc.json'),
emitErrors: true,
failOnHint: true,
typeCheck: true
}
}
})
typeCheck: true,
},
},
}),
],
module: {
rules: [{
test: /\.[t|j]sx?$/,
loader: 'babel-loader',
options: {
babelrc: false,
cacheDirectory: true,
presets: [
[ '@babel/preset-typescript', {
isTSX: true,
allExtensions: true,
jsxPragma: 'createElement'
}],
[ '@babel/preset-env', {
targets: { browsers: ['Chrome 78']},
}]
],
plugins: [
[ '@babel/transform-react-jsx', {
pragma: 'createElement'
}],
[ '@babel/plugin-proposal-class-properties' ]
]
rules: [
{
test: /\.[t|j]sx?$/,
loader: 'babel-loader',
options: {
babelrc: false,
cacheDirectory: true,
presets: [
[
'@babel/preset-typescript',
{
isTSX: true,
allExtensions: true,
jsxPragma: 'createElement',
},
],
[
'@babel/preset-env',
{
targets: { browsers: ['Chrome 78'] },
},
],
],
plugins: [
[
'@babel/transform-react-jsx',
{
pragma: 'createElement',
},
],
['@babel/plugin-proposal-class-properties'],
],
},
},
}]
],
},
devServer: {
@ -76,7 +87,7 @@ export default function() {
`;
app.get('/', (_: any, res: any) => res.send(doc));
}
}
},
},
};
}