profile
viewpoint
Vladimir Kurchatkin vkurchatkin Moscow

vkurchatkin/koa-connect 133

Use connect and express middleware in koa

vkurchatkin/function-origin 50

Get origin of a function in io.js and node.js

vkurchatkin/geojson-flow 9

GeoJSON type declarations for Flow

vkurchatkin/generator-foreach 5

forEach for generators

vkurchatkin/connect-compose 4

Compose connect middleware

vkurchatkin/iojs-ru 1

Перевод io.js на русский язык

vkurchatkin/jquery.couch 1

jquery.couch.js for bower

vkurchatkin/8bit.js 0

8Bit.js Audio Library - Write music using 8bit oscillation sounds.

issue commentJSMonk/hegel

Refinements should be invalidated by side effects

I guess if soundness is the goal, then there is no middle ground

vkurchatkin

comment created time in 3 days

issue commentJSMonk/hegel

refine type of array access to non-undefined given proper for-loop header

There is no way to avoid this check, unless we go into the realm of dependent types

trusktr

comment created time in 4 days

issue commentJSMonk/hegel

Refinements should be invalidated by side effects

You are right. There are a couple of thing that can be done

  1. Purity tracking. Functions that are free of side effects should be marked as such. Properties that are definitely not getters.

  2. Visibilty tracking. This is probably very convoluted in practice. The idea is to prove that a given statement can't possible affect a given refinement, because it doesn't see the refined binding or value.

Simple example:

import { foo } from 'foo';

export function test(x: string | number) {
    if (typeof x === 'string') {
       foo(); // foo is from outer scope, so there is no way it can affect x
    }
}

But this will become convoluted very quickly:

import { foo, bar } from 'foo';

export function test(x: string | number) { bar(() => x = 1);

if (typeof x === 'string') {
   foo(); // foo is from outer scope, but current scope has leaked through `bar`
}

}

vkurchatkin

comment created time in 4 days

issue commentJSMonk/hegel

Unsound `await` handling

Sorry, typo. Fixed the example

vkurchatkin

comment created time in 4 days

issue openedJSMonk/hegel

Unsound `await` handling

async function foo<T>(val: T) {
  const v = await val;
  return v;
}

async function test() {
  const promise = Promise.resolve(1);
  const val = await foo(promise);
  const a = promise.then(); // Runtime error
}

I assume that await and similar promise methods have signature like this:

await<T>(Promise<T> | T) => T;

This is incorrect. If type of T is not known to be a promise (i.e. unknown or generic T), it is assumed NOT to be a promise, while at runtime it could be a promise.

created time in 4 days

issue commentJSMonk/hegel

Incorrect refinement using `instanceof`

That is a separate issue. Refinement is still incorrect

vkurchatkin

comment created time in 4 days

issue commentJSMonk/hegel

Unsound type inference with arithmetic operators

but generics should not allow usage of unions

They should allow it, but that's not what should be inferred in this case.

vkurchatkin

comment created time in 4 days

issue openedJSMonk/hegel

Subtyping functions with optional arguments is unsound

function foo(x: ?string) {
  if (x !== undefined) {
    const val = x.toLowerCase();
  }
}

const foo_: () => undefined = foo; // Either this
const foo__: (x: number) => undefined = foo_; //  or this shouldn't be allowed

foo__(1); // runtime error

created time in 4 days

issue openedJSMonk/hegel

Refinements should be invalidated by side effects

const a:  { a: string | number } = { a: 'foo' };

function foo() {
  a.a = 1;
}

function test(x: { a: string | number }) {
    if (typeof x.a === 'string') {
      foo(); // this invalidates the refinement
      const a: string = x.a.toUpperCase(); // runtime error
    }
}

 test(a);

created time in 4 days

issue openedJSMonk/hegel

Inference doesn't work with recursive functions

function factorial(a) {
  if (a === 1) {
    return 1;
  }

  return a * factorial(a - 1);
}

created time in 4 days

issue openedJSMonk/hegel

Unsound subclassing is allowed

class A {
  foo() {
    return 1;
  }
}

class B extends A {
  foo() {
    return ''; // this shouldn't be allowed
  }
}

const b: A = new B;
const val = b.foo().toFixed(); // runtime error

created time in 4 days

issue openedJSMonk/hegel

Incorrect refinement using `instanceof`

Example:

class A {
  foo(x: string) {
  }
}

class B extends A {
  foo(x: number) {
    return x.toFixed();
  }
}

function test(a: A | B | {}) {
  if (a instanceof A) {
    a.foo('')
  }
}

a is refined to be an A instead of A | B, which leads to a runtime error.

created time in 4 days

issue openedJSMonk/hegel

Unsound type inference with '+' operator

Consider the following function:

let f = (a, b) => a + b

The inferred type is

<T: bigint | number | string>(T, T) => T

This might seem correct, but actually is unsound:

let f = (a, b) => a + b

const a: number | bigint = 1;
const b: number | bigint = 1n;

const x = f(a, b); // TypeError thrown

created time in 4 days

issue commentfacebook/react

Bug: Typing Fast into Controlled Input doesn't change value visually immediately

Well, I guess the devtools are able to observe these changes faster then your app can process them. That is surprising to me, but still unrelated to React.

anatolzak

comment created time in 4 days

issue commentfacebook/react

Bug: Typing Fast into Controlled Input doesn't change value visually immediately

Well, seems like the problem with your app then.

anatolzak

comment created time in 4 days

issue commentfacebook/react

Bug: Typing Fast into Controlled Input doesn't change value visually immediately

There is no way to tell, unless you provide your code

anatolzak

comment created time in 4 days

issue openedreactjs/rfcs

[Feature request] error handling in useTransition

I propose adding the ability to handle errors in useTransition.

Example

const [startTransition, isPending] = useTransition({
    timeoutMs: 3000
 });

const [state, setState] = React.useState();

function loadData() {
   startTransition((controller) => {
      setState('foo');

      return {
          onError: (err) => {
               alert('Failed to fetch the data!');
               controller.abort();
           }
      };
   }

Explanation

Callback object

The function that is passed to startTransition returns a callback object, that can be used to notify the caller about transition state changes. onError is called if the corresponding Suspense boundary caught and error while rendering this transition.

Controller object

The function that is passed to startTransition receives a controller object, that can be use to abort transition. controller.abort() can be called at any time before the transition is complete. If it is called when transition is pending, the whole suspended "branch" is discarded, as if the transition never started.

If controller.abort() is called in onError handler, this prevents the error from propagating to ErrorBoundary.

created time in 6 days

issue commentfacebook/react

Bug: useState's setState may change your state to 'undefined'

It seems that your state is a function. In that case, setState(state) won't work as expected

LXSMNSYC

comment created time in 8 days

issue commentfacebook/react

Bug: react-hooks/exhaustive-deps lint rule not working as expected

Well, this looks like a normal hook to me, except for the part where you alias alert as userAlert. useAlert implies that it is a hook, which it isn't.

Attrash-Islam

comment created time in 14 days

issue commentfacebook/react

[eslint-plugin-react-hooks] false positive with useFocusEffect

Admittedly, useFocusEffect is weird. It could easily work exactly like useEffect instead of requiring useCallback. Also you could probably just use useIsFocused + useEffect to avoid this issue

leethree

comment created time in 14 days

issue commentfacebook/react

Bug: react-hooks/exhaustive-deps lint rule not working as expected

If you just want to trick eslint, use eslint-disable-next-line directive. But you are really just not using hooks correctly

Attrash-Islam

comment created time in 15 days

issue commentfacebook/react

Bug: react-hooks/exhaustive-deps lint rule not working as expected

why not extending the deps to consider other values

Because there is no good way to know, whether a value is "reactive" other than using conventions. Current conventions are (simplified):

  • A reactive value is a Component property, an argument of a hook or a local variable inside a hook or component;
  • A component is a function with capitalised name
  • A hook is a function that starts with use

mapState is neither a hook nor a component, hence context is not reactive.

Attrash-Islam

comment created time in 15 days

issue commentfacebook/react

Bug: react-hooks/exhaustive-deps lint rule not working as expected

Here is a simple example:

This is fine, obviously:

const foo = 1;

useEffect(() => {}, [foo]);

But this is not:

  const foo = 1;

  function useFoo() {
    useEffect(() => {}, [foo]); // foo is external
  }

  useFoo();

Although at runtime they both do the same thing.

Attrash-Islam

comment created time in 16 days

issue commentfacebook/react

Bug: react-hooks/exhaustive-deps lint rule not working as expected

It doesn't really prove anything. Your code happens to work, but ESLint analyses code in isolation.

Attrash-Islam

comment created time in 16 days

issue commentfacebook/react

Bug: react-hooks/exhaustive-deps lint rule not working as expected

The warning is correct: useAlert is a custom hook and context is an external value, so it is not a valid dependency

Attrash-Islam

comment created time in 16 days

issue commentfacebook/react

Bug (MS Edge): Expected identifier, string or number (White screen)

What makes you think it is cause by React, not by some other part of your app?

Ishtmeet-Singh

comment created time in 18 days

issue commentfacebook/react

[eslint-plugin-react-hooks] async functions should be allowed for custom effects

An Effect has a specific shape and meaning in React, so maybe co-opting it might not be the right move.

Technically, I could, I've thought of that. But useAsyncEffect is the obvious name for what it does. I don't want to choose objectively worse name because of a linter rule.

vkurchatkin

comment created time in 18 days

issue commentfacebook/react

[eslint-plugin-react-hooks] async functions should be allowed for custom effects

Just wanted to offer my perspective. I consider it plain wrong to place restrictions like this on my hooks and if this is intended behaviour, my only option is to drop exhaustive-deps completely

vkurchatkin

comment created time in 18 days

issue commentfacebook/react

Bug: useLayoutEffect callback called twice when a dom node is in a dependency array

The idea is to create a reusable hook which doesn't create a ref object, but accepts a ref

There is no feasible way to detect when such a ref changes. But IMO this is fine. When a hook accepts a DOM ref it is a clear signal to the user, that this ref should not change until the component is unmounted and they should structure their code accordingly.

everdimension

comment created time in 19 days

issue openedfacebook/react

[eslint-plugin-react-hooks] async functions should be allowed for custom effects

Consider the following code:

useAsyncEffect(async () => {
  awair foo()
}, []);

Eslint give the following error:

  11:18  error  Effect callbacks are synchronous to prevent race conditions. Put the async function inside:

useEffect(() => {
  async function fetchData() {
    // You can await here
    const response = await MyAPI.getData(someId);
    // ...
  }
  fetchData();
}, [someId]); // Or [] if effect doesn't need props or state

There are 2 problems with that:

  1. The error is provided by react-hooks/exhaustive-deps, but this has nothing to do with deps or exhaustiveness. I can't disable this warning without disable actually checking for exhaustive deps.
  2. In general the error is bogus. Statement "Effect callbacks are synchronous to prevent race conditions" is only true for built-in effects, and is definitely not true for useAsyncEffect, which built specifically to support asynchronous callbacks.

eslint-plugin-react-hooks version: 4.0.0

The current behavior

react-hooks/exhaustive-deps gives an error for this code

The expected behavior

react-hooks/exhaustive-deps should not give an error for this code

created time in 19 days

issue commentfacebook/react

Bug: useLayoutEffect callback called twice when a dom node is in a dependency array

@bvaughn

If you have to clean up when your DOM node changes, you have two options. First is to use effects, which means that you HAVE to put the node in state:

React.useLayoutEffect(() => {
  if (!domNode) {
     return;
  } 
  const resizeObserver = new ResizeObserver(...);
  ...
  return () => {
     resizeObserver.disconnect();
  }
}, [domNode])

The second is to do it manually:

  const cleanupRef = React.useRef();
  const ref = React.useCallback(domNode => {
    if (cleanupRef.current) {
      cleanupRef.current();
    }

    cleanupRef.current = undefined;

   if (!domNode) {
     return;
   }
     const resizeObserver = new ResizeObserver(...);

     cleanupRef.current =  () => {
        resizeObserver.disconnect();
     };
  }, []);

React.useEffect(() => {
  return () => {
     if (cleanupRef.current) {
      cleanupRef.current();
    }
  };
}, [])

While you can certainly use the second option, and even wrap it in some sort of hook, I would rather just go with the first one.

everdimension

comment created time in 19 days

issue commentfacebook/react

Bug: Previous and next props in memo equality function are the same

I need to return a deep clone of field in getComputedFields in order for react to detect the change

Not deep clone, shallow is enough.

fourstacks

comment created time in 19 days

issue commentfacebook/react

Bug: useLayoutEffect callback called twice when a dom node is in a dependency array

Actually, it is defined

It is defined when useLayoutEffect is executed, but during first render undefined is what you pass inside of dependencies array.

If that's the wrong way, then what's the proper way to update effect if the dom node changes or gets destroyed?

The proper way is to store dom node inside of state:

const [node, setNode] = React.useState(null);

return <div ref={setNode}>My node</div>
everdimension

comment created time in 19 days

issue commentfacebook/react

Bug: useLayoutEffect callback called twice when a dom node is in a dependency array

You are not supposed to use ref.current as a dependency, since changing it doesn't result in a rerender.

There is no bug in React. ref.current is undefined initially, then your effect is triggered, setState is called, which results in a rerender. ref.current is not undefined anymore, so the effect is triggered gain.

everdimension

comment created time in 19 days

issue commentfacebook/react

Bug: Previous and next props in memo equality function are the same

That's because you mutate your field objects in getComputedFormFields. getComputedFormFields always return a new array, but it always contains original objects.

fourstacks

comment created time in 19 days

issue commentJSMonk/hegel

Type named `_` is not allowed

My point is, you shouldn't use _ for a placeholder type for this reason

vkurchatkin

comment created time in 20 days

issue openedJSMonk/hegel

Type named `_` is not allowed

_ is a valid JS identifier and has to be allowed as a proper type identifier:

class _ {}

const t: _ = new _();

created time in 23 days

issue openedJSMonk/hegel

Incorrect property variance with unions

type A = { a: string } | { a: number };
type B = { a: string | number };


const a1: { a: string } = { a: 'foo' };
const a2: A = a1;
const b: B = a2; // <--- this shouldn't be allowed

b.a = 1;

const string = a1.a.toLowerCase(); // runtime error

created time in 23 days

issue commentfacebook/react

Bug: Fetch API not working correctly when using ReadableStream

The problematic code is within useEffect. React just runs it and doesn't affect in any other way. You don't even call any React-related code (such as setState) from there. Then again, React doesn't have any network-related code at all.

If you post this question to Stackoverflow, you'd surely get the help you need.

DonHaul

comment created time in 25 days

issue commentfacebook/react

Bug: Fetch API not working correctly when using ReadableStream

This has nothing to do with React

DonHaul

comment created time in 25 days

issue commentfacebook/react

Bug: rules-of-hooks should support hooks inside top-level IIFEs

Linter rules are based on conventions. It is not possible to support every possible case, so only patterns that are popular are supported.

if I'm understanding things correctly it's completely safe to call hooks this way

It is safe indeed. So is calling a custom hook not use-something, or calling hooks in a loop, if it always has the same number of iterations. None of this is supported.

fabiospampinato

comment created time in a month

issue commentfacebook/react

Bug: rules-of-hooks should support hooks inside top-level IIFEs

This pattern seems rather pointless. Why would you do that?

fabiospampinato

comment created time in a month

issue commentfacebook/react

useEffect is never invoked in suspended component

I'm not sure is this is the expected behaviour or a bug.

This is expected. useEffect is triggered after a component is rendered and committed. If it is suspended, it's not going to happen

JoseExposito

comment created time in a month

issue commentfacebook/react

Bug: React Context API is not working from custom NPM library

If there actually is a bug in React, it shouldn't be a problem to make a single file reproduction. After all, that what bundlers do: they build a single JS file. Build your bundle, remove all the webpack cruft, and you'll have it.

ayayalar

comment created time in a month

issue commentfacebook/react

Bug: React Context API is not working from custom NPM library

React works the same regardless of whether you have a single file or not, whether you use a bundler or not. If you have a problem with context you need to ensure that provider and consumer really use the same Context object. It is most likely that they are not

ayayalar

comment created time in a month

issue commentfacebook/react

Bug: React Context API is not working from custom NPM library

If you can't reproduce it using a single a file, it is a problem with your build configuration, not React

ayayalar

comment created time in a month

issue commentfacebook/react

React Hooks will render multiple times after await

This is inevitable: when you run your code asynchronously, React has no way of knowing that more synchronous setters could be executed after the current one, so it has to trigger render for each. You can either batch by making a single state object, like you did, or use unstable_batchedUpdates:

import {unstable_batchedUpdates as batchedUpdates} from 'react-dom';

// ....

const [ html, setHTML ] = useState('');
const [ script, setScript ] = useState('');

const update = async (script, html) => {
  await new Promise(resolve => setTimeout(resolve, 10));
    batchedUpdates(() => {
        setScript(script);
        setHTML(html);
    });
};

update('a', 'b');
aeroxy

comment created time in a month

issue commentfacebook/react

Bug: function component cannot have ref property

Oh, that's right, forwardRef is a misnomer, it's just the way to access ref property within your component. If you name it differently, say myRef, you don't need forwardRef and can just use seImperativeHandle

vhermecz

comment created time in a month

issue commentfacebook/react

Bug: Unable to use resolve Context when component and Provider exist on different levels of NPM module.

This has nothing to do with React. React is unaware of your directory structure.

CrashyBang

comment created time in a month

issue commentfacebook/react

Suspense prevents reading valid layout values in `useLayoutEffect`

Documentation clearly states:

Use this to read layout from the DOM and synchronously re-render.

So I assume this has to be a bug

vkurchatkin

comment created time in a month

issue openedfacebook/react

Suspense prevents reading valid layout values in `useLayoutEffect`

useLayoutEffect is commonly used to read layout values (such as getClientBoundingRect) to adjust positioning of some elements:

const ref = React.useRef();

useLayoutEffect(() => {
  const width = ref.current.getBoundingClientRect().width;
  // do something with width
});

This breaks if such a component is rendered within suspended React.Suspense boundary:

let shouldSuspend = true;

function A() {
  if (shouldSuspend) {
    shouldSuspend = false;
    throw Promise.resolve(); // if you comment this out, works as expected
  }

  return <div>A</div>;
}

function B() {
  const ref = React.useRef();

  React.useLayoutEffect(() => {
    console.log(ref.current.offsetWidth); // returns 0
  });

  return <div ref={ref}>B</div>;
}

export default function App() {
  return (
    <div className="App">
      <Suspense fallback={<div />}>
        <A />
        <B />
      </Suspense>
    </div>
  );
}

React version: 16.13.1

Link to code example:

https://codesandbox.io/s/small-leaf-h31xt?file=/src/App.js:108-189

The current behavior

Effects run before layout within suspended Suspense boundary

The expected behavior

Effects run after layout within suspended Suspense boundary

created time in a month

issue commentJSMonk/hegel

disallow non strict comparison

which i think should not be allowed in sound type system)

This has nothing to do with soundness. == is perfectly safe and even sometimes useful.

thecotne

comment created time in a month

issue commentfacebook/react

Bug: function component cannot have ref property

You need to use forwardRef for this: https://reactjs.org/docs/forwarding-refs.html

vhermecz

comment created time in a month

issue commentfacebook/react

Bug: Context value change results in rendering of components that do not consume said context

This is how React works. When you update state the component is rerendered, including all of the descendants, unless there is a React.memo somewhere

lee-borsboom

comment created time in a month

issue commentfacebook/react

Bug: react-hooks/exhaustive-deps not warning about unneeded dep

There is no such thing as "unneeded dependency" in useEffect. You might not use a variable, but still want to trigger effect when it changes

tonix-tuft

comment created time in a month

issue commentJSMonk/hegel

Properties in function arguments should be invariant

No, it's not ok. Here is a simple example of a runtime error:

function foo(obj: { a : number | string }) {
    obj.a = 'foo';
}

const f: ({ a: number}) => undefined = foo; 

const obj = { a: 1 };

f(obj);

obj.a.toFixed(); // BOOM
vkurchatkin

comment created time in a month

issue openedJSMonk/hegel

Property refinements are unsound

function test(x: { a: string | number }): { a: string } | undefined {
    if (typeof x.a === 'string') {
        return x;
    }
}

const a:  { a: string | number } = { a: 'foo' };
const b = test(a);

a.a = 1;

if (b !== undefined) {
    b.a.toUpperCase(); // runtime error
}

created time in a month

issue openedJSMonk/hegel

Properties in function arguments should be invariant

Small example:

const a: { a: number} = { a: 1 };
const b: {a : number | string } = a; // CORRECT, not allowed


function foo(obj: { a : number | string }) {}
const f: ({ a: number}) => undefined = foo; // INCORRECT, allowed

created time in a month

issue commentfacebook/react

[react-hooks/exhaustive-deps] function outside the hook

You are free to ignore linter if that's what you want

eshturman

comment created time in 2 months

issue commentfacebook/react

Bug: cursor jumps to end of controlled <input> tag when value is modified

Is this something that could/should be added as default behavior for the <input> component?

I think it is a bit against React philosophy. React is about making DOM transformations declarative, not about changing how it works. If you need such behaviour, you can make your own <Input/> component which does just that (or more).

The example in the documentation would benefit from this.

I agree, there probably should be a warning in the docs explaining that it's not as _ straightforward_ to modify input this way.

If you modify your handleChange function to the following, it should work as expected.

No, your modified code is strictly equivalent to original code. What you can't do is use the event object asynchronously, including setState(() => ...) form, without calling e.persist().

iain-merrick-fanduel

comment created time in 2 months

issue commentfacebook/react

Bug: cursor jumps to end of controlled <input> tag when value is modified

But React doesn't provide that low-level access (by design).

Well, that's where you are wrong. It's not that hard to implement this in React. Here is a demo: https://codesandbox.io/s/boring-dirac-utq82

iain-merrick-fanduel

comment created time in 2 months

issue commentfacebook/react

Bug: cursor jumps to end of controlled <input> tag when value is modified

This has nothing to do with React, that's normal browser behaviour

iain-merrick-fanduel

comment created time in 2 months

issue commentfacebook/react-native

Unable to resolve module http

You are trying to run node.js app with React Native runtime. This is probably a mistake, but either way this won't work

imanolpg

comment created time in 2 months

issue commentfacebook/react

[Feature Request] Allow dependency length to change in hooks

Generally in React you should:

  • use immutable structures
  • use pure functions to transform immutable structures

If you follow these two rules, then useMemo just works.

is derived itself, a list of ids mapped against a dictionary

If it is derived, then you should derive it using useMemo as well

georeith

comment created time in 3 months

issue commentfacebook/react

Bug: [eslint-plugin-react-hooks] exhaustive-deps doesn't allow for array hashing

There should be some way to do this?

There is: eslint-disable-next-line

cowboy

comment created time in 3 months

issue commentfacebook/react

[Feature Request] Allow dependency length to change in hooks

This is seems like a non-problem: just add an array itself as a single dependency.

georeith

comment created time in 3 months

issue commentfacebook/react

Bug: hook return setter losts its effect when assign it to some obj after click its dom node in react-dev-tool

The point is that people (myself included) often break React rules thinking that they know what they are doing.

Side effects in render is a good example. You are clearly discouraged to do so, but React says that setState is guaranteed to not changed, so you would assume that is ok to do that. Except it is not, and figuring out why can be difficult. The fact that DevTools disable console to hide this render makes it even more confusing.

All I’m saying that docs should mention that fact that you might observe alternative setState functions if you break React rules, or something like this.

fantasticsoul

comment created time in 3 months

issue commentfacebook/react

Bug: hook return setter losts its effect when assign it to some obj after click its dom node in react-dev-tool

Yes, that’s probably the case in practice, but it is never said in the docs that you MUST assign ref value during the first render. In theory it is possible that is for some reason assigned during DevTools render. That would probably require reading some external mutable value, which is not recommended, but people do it all the time

fantasticsoul

comment created time in 3 months

issue commentfacebook/react

Bug: hook return setter losts its effect when assign it to some obj after click its dom node in react-dev-tool

Documentation explicitly allows assigning to ref.current for lazy initialisation which makes it possible to observe invalid setState

fantasticsoul

comment created time in 3 months

issue commentfacebook/react

Bug: hook return setter losts its effect when assign it to some obj after click its dom node in react-dev-tool

@bvaughn documentation clearly says:

React guarantees that setState function identity is stable and won’t change on re-renders.

And it seems that it is Dev Tools break this guarantee

fantasticsoul

comment created time in 3 months

issue commentfacebook/react

[eslint-plugin-react-hooks] Bug: exhaustive-deps not working with function declaration

Consider this: you often extract some code into components, although it is used only in one place. You do this to make it easier to read and reason about code, not for reuse. The same applies to hooks.

yuriybelike

comment created time in 3 months

issue commentfacebook/react

[eslint-plugin-react-hooks] Bug: exhaustive-deps not working with function declaration

the code is coupled to the component and is not really reusable

This shouldn't be matter. You can have your hook unexported in the same file, with a meaningful name.

yuriybelike

comment created time in 3 months

issue commentfacebook/react

[eslint-plugin-react-hooks] Bug: exhaustive-deps not working with function declaration

Never do this. There is no good reason to do this, but it is very hard to make exhaustive-deps support this pattern

yuriybelike

comment created time in 3 months

more