This update to the RulesOfHooks rule checks that functions created with
`useEvent` can only be invoked in a `useEffect` callback, in another
event function, or a closure.
They can't be passed down directly as a reference to child components.
This PR also updates the ExhaustiveDeps lint rule to treat useEvent's
return value as stable, so it can be omitted from dependency lists.
Currently this all gated behind an experimental flag.
Co-authored-by: Dan Abramov <dan.abramov@gmail.com>
Similar to Fizz, Flight now supports a return value from the user provided onError option. If a value is returned from onError it will be serialized and provided to the client.
The digest is stashed on the constructed Error on the client as .digest
* Expose ref to Offscreen if mode is manual
* Prepend private fields on OffscreenInstance with underscore
* Schedule Ref effect unconditionally on Offscreen
* Make sure Offscreen's ref is detached when unmounted
* Make sure ref is mounted/unmounted in all scenarious
* Nit: pendingProps -> memoizedProps
Co-authored-by: Andrew Clark <git@andrewclark.io>
Enables well formed exports for /scheduler. Some of the modules there were missing `@flow` and were therefore completely unchecked (despite some spurious types sprinkled around).
To enable the next Flow version, we need to annotate exported values. This adds a few automatically inferred types that didn't look huge or just `any`.
There's a global queue (`concurrentQueues` in the
ReactFiberConcurrentUpdates module) that is cleared at the beginning of
each render phase.
However, in the case of an eager `setState` bailout where the state is
updated to same value as the current one, we add the update to the queue
without scheduling a render. So the render phase never removes it from
the queue. This can lead to a memory leak if it happens repeatedly
without any other updates.
There's only one place where this ever happens, so the fix was pretty
straightforward.
Currently there's no great way to test this from a Jest test, so I
confirmed locally by checking in an existing test whether the array gets
reset. @sompylasar had an interesting suggestion for how to catch these
in the future: in the development build (perhaps behind a flag), use a
Babel plugin to instrument all module-level variables. Then periodically
sweep to confirm if something has leaked. The logic is that if there's
no React work scheduled, and a module-level variable points to an
object, it very likely indicates a memory leak.
* [Flight] Move from suspensey readRoot() to use(thenable)
* Update noop tests
These are no longer sync so they need some more significant updating.
Some of these tests are written in a non-idiomatic form too which is not
great.
* Update Relay tests
I kept these as sync for now and just assume a sync Promise.
* Updated the main tests
* Gate tests
* We need to cast through any because Thenable doesn't support unknown strings
* [Flight] Align Chunks with Thenable used with experimental_use
Use the field names used by the Thenable data structure passed to use().
These are considered public in this model.
This adds another field since we use a separate field name for "reason".
* Implement Thenable Protocol on Chunks
This doesn't just ping but resolves/rejects with the value.
* Subclass Promises
* Pass key through JSON parsing
* Wait for preloadModules before resolving module chunks
* Initialize lazy resolved values before reading the result
* Block a model from initializing if its direct dependencies are pending
If a module is blocked, then we can't complete initializing a model.
However, we can still let it parse, and then fill in the missing pieces
later.
We need to block it from resolving until all dependencies have filled in
which we can do with a ref count.
* Treat blocked modules or models as a special status
We currently loop over all chunks at the end to error them if they're
still pending. We shouldn't do this if they're pending because they're
blocked on an external resource like a module because the module might not
resolve before the Flight connection closes and that's not an error.
In an alternative solution I had a set that tracked pending chunks and
removed one at a time. While the loop at the end is faster it's more
work as we go.
I figured the extra status might also help debugging.
For modules we can probably assume no forward references, and the first
async module we can just use the promise as the chunk.
So we could probably get away with this only on models that are blocked by
modules.
This commit adds a new hook `useEvent` per the RFC [here](https://github.com/reactjs/rfcs/pull/220), gated as experimental.
Co-authored-by: Rick Hanlon <rickhanlonii@gmail.com>
Co-authored-by: Rick Hanlon <rickhanlonii@fb.com>
Co-authored-by: Lauren Tan <poteto@users.noreply.github.com>
- `~/.yarn/cache` is now restored from an hierarchical cache key, if no precise match is found, we fallback to less precise ones.
- The yarn install in `fixtures/dom` is also cached. Notably, is utilizes the cache from root, but stores into its more precise key.
- Steps running in root no longer have a `yarn install` and rely on the cache from the setup step.
- Retry `yarn install` once on failure.
* useMemoCache impl
* test for multiple calls in a component (from custom hook)
* Use array of arrays for multiple calls; use alternate/local as the backup
* code cleanup
* fix internal test
* oops we do not support nullable property access
* Simplify implementation, still have questions on some of the PR feedback though
* Gate all code based on the feature flag
* refactor to use updateQueue
* address feedback
* Try to eliminate size increase in prod bundle
* update to retrigger ci
add more accurate end time for transitions and update host configs with `requestPostPaintCallback` function and move post paint logic to another module and use it in the work loop
This update range includes:
- `types_first` ([blog](https://flow.org/en/docs/lang/types-first/), all exports need annotated types) is default. I disabled this for now to make that change incremental.
- Generics that escape the scope they are defined in are an error. I fixed some with explicit type annotations and some are suppressed that I didn't easily figure out.
Usually we complete workInProgress before yielding but if that's the
currently suspended one, we don't yet complete it in case we can
immediately unblock it.
If we get interrupted, however, we must unwind it. Where as we usually
assume that we've already completed it.
This shows up when the current work in progress was a Context that pushed
and then it suspends in its immediate children. If we don't unwind,
it won't pop and so we get an imbalance.
* Prevent infinite re-render in StrictMode + Offscreen
* Only fire effects for Offscreen when it is revealed
* Move setting debug fiber into if branch
* Move settings of debug fiber out of if branch
With this change, a simple object type `{ }` means an exact object `{| |}` which most people assume.
Opting for inexact requires the extra `{ a: number, ... }` syntax at the end.
A followup, someone could replace all the `{| |}` with `{ }`.
Follow up to #25084 and #25207. Implements experimental_use(promise) API
in the SSR runtime (Fizz).
This is largely a copy-paste of the Flight implementation. I have
intentionally tried to keep both as close as possible.