Commit Graph

119 Commits

Author SHA1 Message Date
Dominic Gannaway a9eff329c6 Remove TouchHitTarget SSR logic to prevent issues with mouse events (#15381) 2019-04-11 12:05:26 +01:00
Dominic Gannaway 4fbbae8afa Add full TouchHitTarget hit slop (experimental event API) to ReactDOM (#15308) 2019-04-06 07:51:21 +01:00
Dominic Gannaway c6f3524df5 Adds React event component and React event target support to SSR renderer (#15242)
* Adds React event component and React event target support to SSR renderer
2019-03-28 15:36:21 -07:00
Dan Abramov c05b4b81f9 Link to useLayoutEffect gist in a warning (#15158) 2019-03-20 13:40:36 +00:00
Sebastian Markbåge acd65db5bc Deprecate module pattern (factory) components (#15145) 2019-03-19 12:55:27 -07:00
Dan Abramov 7ad7386308 Improve warning for invalid class contextType (#15142)
* Improve warning for invalid class contextType

* Don't warn for null

* Grammar
2019-03-19 13:31:26 +00:00
Brandon Dail df7b87d25e Warn for Context.Consumer with contextType (#14831) 2019-03-18 19:27:05 +00:00
Jared Palmer 2b93d686e3 Add more info to invalid hook call error message (#15139)
* Add more info to invalid hook call error message

* Update other renderers + change call to action

* Update related tests for new hooks error message

* Fix lint errors
2019-03-18 18:22:38 +00:00
Sebastian Markbåge 103378b1ea Warn for javascript: URLs in DOM sinks (#15047)
* Prevent javascript protocol URLs

* Just warn when disableJavaScriptURLs is false

This avoids a breaking change.

* Allow framesets

* Allow <html> to be used in integration tests

Full document renders requires server rendering so the client path
just uses the hydration path in this case to simplify writing these tests.

* Detect leading and intermediate characters and test mixed case

These are considered valid javascript urls by browser so they must be
included in the filter.

This is an exact match according to the spec but maybe we should include
a super set to be safer?

* Test updates to ensure we have coverage there too

* Fix toString invocation and Flow types

Right now we invoke toString twice when we hydrate (three times
with the flag off). Ideally we should only do it once even in this case
but the code structure doesn't really allow for that right now.

* s/itRejects/itRejectsRendering

* Dedupe warning and add the unsafe URL to the warning message

* Add test that fails if g is added to the sanitizer

This only affects the prod version since the warning is deduped anyway.

* Fix prod test
2019-03-11 16:39:49 -07:00
Sebastian Markbåge 13645d224d Deal with fallback content in Partial Hydration (#14884)
* Replace SSR fallback content with new suspense content

* The three states of a Dehydrated Suspense

This introduces three states for dehydrated suspense boundaries

Pending - This means that the tree is still waiting for additional data or
to be populated with its final content.

Fallback - This means that the tree has entered a permanent fallback state
and no more data from the server is to be expected. This means that the
client should take over and try to render instead. The fallback nodes will
be deleted.

Normal - The node has entered its final content and is now ready to be
hydrated.

* Rename retryTimedOutBoundary to resolveRetryThenable

This doesn't just retry. It assumes that resolving a thenable means that
it is ok to clear it from the thenable cache.

We'll reuse the retryTimedOutBoundary logic separately.

* Register a callback to be fired when a boundary changes away from pending

It's now possible to switch from a pending state to either hydrating
or replacing the content.
2019-02-19 13:07:41 -08:00
overlookmotel ab7a67b1dc Fix react-dom/server context leaks when render stream destroyed early (#14706)
* Fix react-dom/server context memory retention

* Test for pollution of later renders

* Inline loop

* More tests
2019-02-14 19:50:23 +00:00
Sebastian Markbåge f3a14951ab Partial Hydration (#14717)
* Basic partial hydration test

* Render comments around Suspense components

We need this to be able to identify how far to skip ahead if we're not
going to hydrate this subtree yet.

* Add DehydratedSuspenseComponent type of work

Will be used for Suspense boundaries that are left with their server
rendered content intact.

* Add comment node as hydratable instance type as placeholder for suspense

* Skip past nodes within the Suspense boundary

This lets us continue hydrating sibling nodes.

* A dehydrated suspense boundary comment should be considered a sibling

* Retry hydrating at offscreen pri or after ping if suspended

* Enter hydration state when retrying dehydrated suspense boundary

* Delete all children within a dehydrated suspense boundary when it's deleted

* Delete server rendered content when props change before hydration completes

* Make test internal

* Wrap in act

* Change SSR Fixture to use Partial Hydration

This requires the enableSuspenseServerRenderer flag to be manually enabled
for the build to work.

* Changes to any parent Context forces clearing dehydrated content

We mark dehydrated boundaries as having child work, since they might have
components that read from the changed context.

We check this in beginWork and if it does we treat it as if the input
has changed (same as if props changes).

* Wrap in feature flag

* Treat Suspense boundaries without fallbacks as if not-boundaries

These don't come into play for purposes of hydration.

* Fix clearing of nested suspense boundaries

* ping -> retry

Co-Authored-By: sebmarkbage <sebastian@calyptus.eu>

* Typo

Co-Authored-By: sebmarkbage <sebastian@calyptus.eu>

* Use didReceiveUpdate instead of manually comparing props

* Leave comment for why it's ok to ignore the timeout
2019-02-11 21:25:44 -08:00
Dan Abramov c21c41ecfa Tweak invalid Hook warning and error (#14747) 2019-02-01 21:05:13 +00:00
Andrew Clark 66eb293742 Restrict effect return type to a function or nothing (#14119)
* Restrict effect return type to a function or nothing

We already warn in dev if the wrong type is returned. This updates the
Flow type.

* Restrict return type further

* Assume Effect hook returns either a function or undefined

* Tweak warning message
2019-01-31 10:11:47 -08:00
Andrew Clark ba6477aa3c Improve Reducer Hook's lazy init API (#14723)
* Improve Reducer Hook's lazy init API

* Use generic type for initilizer input

Still requires an `any` cast in the case where `init` function is
not provided.
2019-01-29 17:39:24 -08:00
Andrew Clark cb1ff430e8 Phased dispatcher (#14701)
* Move DEV-only function right above where it's used

I don't like looking at this top-level function #petty

* Use different dispatchers for functions & classes

Classes support readContext, but not any of the other dispatcher
methods. Function support all methods.

This is a more robust version of our previous strategy of checking
whether `currentlyRenderingFiber` is null.

As a next step, we can use a separate dispatcher for each phase of the
render cycle (mount versus update).

* Use separate dispatchers for mount and update

* Remove mount code from update path

Deletes mount-specific code from the update path, since it should be
unreachable. To continue supporting progressive enhancement (mounting
new hooks at the end of the list), we detect when there are no more
current hooks and switch back to the mount dispatcher. Progressive
enhancement isn't officially supported yet, so it will continue to warn.

* Factoring nits

* Fix Flow

Had to cheat more than I would like

* More Flow nits

* Switch back to using a special dispatcher for nested hooks in DEV

In order for this strategy to work, I had to revert progressive
enhancement support (appending hooks to the end). It was previously a
warning but now it results in an error. We'll reconsider later.

* Always pass args to updateState and updateReducer

Even though the extra args are only used on mount, to ensure
type consistency.
2019-01-29 16:32:15 -08:00
Dan Abramov 8bcc88f2e7 Make all readContext() and Hook-in-a-Hook checks DEV-only (#14677)
* Make readContext() in Hooks DEV-only warning

* Warn about readContext() during class render-phase setState()

* Warn on readContext() in SSR inside useMemo and useReducer

* Make all Hooks-in-Hooks warnings DEV-only

* Rename stashContextDependencies

* Clean up warning state on errors
2019-01-24 19:31:20 +00:00
Brian Vaughn 6cb26774e2 Enable hooks! (#14679)
* Turned enableHooks feature flag on everywhere
* Removed useHooks feature flag from tests (now that it's on by default)
* Remove useHooks feature flag entirely
2019-01-23 13:28:09 -08:00
Sunil Pai e1cd83e49d Throw an error when using hooks inside useMemo/useState/useReducer, or .memo's comparator (#14608)
* hooks inside useMemo/.memo - failing tests

* throw an error when using hooks inside useMemo

* throw when using hooks inside .memo's compare fn

* faster/better/stronger

* same logic for useReducer, tests for the server, etc

* Update ReactDOMServerIntegrationHooks-test.internal.js

ack lint

* nits

* whitespace

* whitespace

* stray semi

* Tweak comment

* stray unmatched fiber reset

* nit
2019-01-18 02:15:21 +00:00
Dan Abramov be457ca685 Small tweaks to SSR to match #14594 (#14618)
* Small tweaks to SSR to match #14594

* Remove unnecessary comparison
2019-01-18 00:52:13 +00:00
Andrew Clark 1454a8be03 Don't bother comparing constructor when deps are not provided (#14594)
* Don't bother comparing constructor when deps are not provided

When no dependencies are passed to an effect hook, what we used to do is
compare the effect constructor. If there was no change, then we would
skip firing the effect. In practice, this is a useless optimization
because the constructor will always be different when you pass an inline
closure. And if you don't pass an inline closure, then you can't access
any props or state.

There are some edge cases where an effect that doesn't close over props
or state could be useful, like reference counting the number of mounted
components. But those are rare and can be addressed by passing an empty
array of dependencies.

By removing this "optimization," we can avoid retaining the constructor
in the majority of cases where it's a closure that changes on
every render.

I made corresponding changes to the other hooks that accept
dependencies, too (useMemo, useCallback, and useImperativeHandle).

* Improve hook dependencies warning

It now includes the name of the hook in the message.

* Nits
2019-01-16 17:53:48 -08:00
Brian Vaughn 7ab8a8e979 Added Flow type to keep hooks dispatchers in-sync (#14599)
* Added Flow type to keep hooks dispatchers in-sync
2019-01-16 12:49:31 -08:00
Brian Vaughn 153a0b5980 Add noop useDebugValue hook to partial/server renderer (#14597) 2019-01-15 11:00:03 -08:00
Sunil Pai b4ad8e9471 rename useImperativeMethods -> useImperativeHandle (#14565) 2019-01-10 13:37:50 +00:00
Brian Vaughn 19ef0ec116 Separate current owner and dispatcher (#14548) 2019-01-08 14:39:52 -08:00
Sebastian Markbåge 1d25aa5787 [Fizz] New Server Rendering Infra (#14144)
* [Fizz] Add Flow/Jest/Rollup build infra

Add a new package for react-stream which allows for custom server renderer
outputs. I picked the name because it's a reasonable name but also
because the npm name is currently owned by a friend of the project.

The react-dom build has its own inlined server renderer under the
name `react-dom/fizz`.

There is also a noop renderer to be used for testing. At some point
we might add a public one to test-renderer but for now I don't want to have
to think about public API design for the tests.

* Add FormatConfig too

We need to separate the format (DOM, React Native, etc) from the host
running the server (Node, Browser, etc).

* Basic wiring between Node, Noop and DOM configs

The Node DOM API is pipeToNodeStream which accepts a writable stream.

* Merge host and format config in dynamic react-stream entry point

Simpler API this way but also avoids having to fork the wrapper config.

Fixes noop builds.

* Add setImmediate/Buffer globals to lint config

Used by the server renderer

* Properly include fizz.node.js

Also use forwarding to it from fizz.js in builds so that tests covers
this.

* Make react-stream private since we're not ready to publish

or even name it yet

* Rename Renderer -> Streamer

* Prefix react-dom/fizz with react-dom/unstable-fizz

* Add Fizz Browser host config

This lets Fizz render to WHATWG streams. E.g. for rendering in a
Service Worker.

I added react-dom/unstable-fizz.browser as the entry point for this.

Since we now have two configurations of DOM. I had to add another
inlinedHostConfigs configuration called `dom-browser`. The reconciler
treats this configuration the same as `dom`. For stream it checks
against the ReactFizzHostConfigBrowser instead of the Node one.

* Add Fizz Browser Fixture

This is for testing server rendering - on the client.

* Lower version number to detach it from react-reconciler version
2018-11-30 11:38:22 -08:00
Sophie Alpert c2a2d8a539 Remove useMutationEffect (#14336)
useMutationEffect has problems (namely, refs aren't attached at the time that it runs) and we're not positive it's necessary. useLayoutEffect runs at the same time as componentDidMount/Update so it's sufficient for all existing use cases; it can be used in any case that useEffect happens too late. Until we figure out what we want to do, let's delete it.
2018-11-27 13:05:13 -08:00
Pelle Wessman ee3ef3a079 Fix regression: Errors not emitted in streams (#14314)
Regression introduced in #14182 resulted in errors no longer being emitted on streams, breaking many consumers.

Co-authored-by: Elliot Jalgard <elliot.j@live.se>
2018-11-27 13:00:46 +00:00
Dan Abramov dc0dd4bbff Use |0 to coerce to number (#14297) 2018-11-22 15:44:00 +00:00
Dan Abramov 327cf0ee33 Fix support for mixing react-dom/server@16.6 and react@<16.6 (#14291) 2018-11-20 13:09:44 +00:00
Dan Abramov ccb14e270c Fix SSR useCallback in render phase (#14279) 2018-11-19 20:47:38 +00:00
Sebastian Markbage f8bfd58680 fix typo 2018-11-09 16:16:25 -08:00
Sebastian Markbåge 961eb65b4b Use unique thread ID for each partial render to access Context (#14182)
* BUG: ReactPartialRenderer / New Context polutes mutable global state

The new context API stores the provided values on the shared context instance. When used in a synchronous context, this is not an issue. However when used in an concurrent context this can cause a "push provider" from one react render to have an effect on an unrelated concurrent react render.

I've encountered this bug in production when using renderToNodeStream, which asks ReactPartialRenderer for bytes up to a high water mark before yielding. If two Node Streams are created and read from in parallel, the state of one can polute the other.

I wrote a failing test to illustrate the conditions under which this happens.

I'm also concerned that the experimental concurrent/async React rendering on the client could suffer from the same issue.

* Use unique thread ID for each partial render to access Context

This first adds an allocator that keeps track of a unique ThreadID index
for each currently executing partial renderer. IDs are not just growing
but are reused as streams are destroyed.

This ensures that IDs are kept nice and compact.

This lets us use an "array" for each Context object to store the current
values. The look up for these are fast because they're just looking up
an offset in a tightly packed "array".

I don't use an actual Array object to store the values. Instead, I rely
on that VMs (notably V8) treat storage of numeric index property access
as a separate "elements" allocation.

This lets us avoid an extra indirection.

However, we must ensure that these arrays are not holey to preserve this
feature.

To do that I store the _threadCount on each context (effectively it takes
the place of the .length property on an array).

This lets us first validate that the context has enough slots before we
access the slot. If not, we fill in the slots with the default value.
2018-11-09 15:38:20 -08:00
Heaven 1034e26fe5 Fix typos (#14124) 2018-11-09 10:17:49 -08:00
Alex Taylor 02e4848e3a Improved suspense support in ReactDOMServer (#14161) 2018-11-08 18:15:06 -08:00
Dominic Gannaway aa1ffe4e77 Show deprecated context object warnings usage in ReactDOM server (#14033)
* Applies context object warnings to ReactDOM server
2018-11-07 17:19:38 +00:00
Dan Abramov 600651e68e Restore the Hooks dispatcher after using SSR (#14105) 2018-11-06 01:15:11 +00:00
Sophie Alpert ebdb47d2c1 DCE hooks code when flag is off (#14111) 2018-11-05 13:04:57 -08:00
Mateusz Burzyński ae196e84b6 Rename inputsAreEqual to areHookInputsEqual & move it to shared (#14036) 2018-11-02 12:50:23 -07:00
Andrew Clark bf9fadfcf4 [Hooks] Remove dispatch callbacks (#14037)
Removes the `enableDispatchCallback` feature flag and deletes the
associated code. An earlier version of the Hooks proposal included this
feature but we've since decided to remove it.
2018-10-30 14:14:20 -07:00
Andrew Clark 5045763064 Swap order of function member in hook union types 2018-10-29 11:42:41 -07:00
Sophie Alpert 5fc84efacc Skip updating effect tag when skipping effect
For example, if you have `useEffect(..., [])`, there's no need to set .effectTag to `Update | Passive` on updates.
2018-10-29 11:26:54 -07:00
Alex Taylor 9f34eb79a3 Add readContext to ReactPartialRendererHooks 2018-10-29 11:26:54 -07:00
Sebastian Markbåge b772e0e26b "functional component" -> "function component" in hooks error messages 2018-10-29 11:26:53 -07:00
Alex Taylor dd019d34db Add support for hooks to ReactDOMServer
Co-authored-by: Alex Taylor <alexmckenley@gmail.com>
Co-authored-by: Andrew Clark <acdlite@fb.com>
2018-10-29 11:26:53 -07:00
Dan Abramov 769b1f270e pure -> memo (#13905) 2018-10-20 12:46:23 -04:00
Alex Taylor 8ecd4bd4f0 Add support for React.pure in ReactDOMServer (#13855)
* Add support for React.pure in ReactDOMServer

* Unwrap pure wrappers by creating an additional element as a single child

This is very slow but meh. We're rewriting this whole thing anyway.
2018-10-20 00:42:33 -07:00
Sebastian Markbåge 6938dcaacb SSR support for class contextType (#13889) 2018-10-19 11:18:32 -07:00
Sebastian Markbåge fa65c58e15 Add readContext to SSR (#13888)
Will be used by react-cache.
2018-10-18 20:20:03 -07:00
Andrew Clark d9659e499e Lazy components must use React.lazy (#13885)
Removes support for using arbitrary promises as the type of a React
element. Instead, promises must be wrapped in React.lazy. This gives us
flexibility later if we need to change the protocol.

The reason is that promises do not provide a way to call their
constructor multiple times. For example:

const promiseForA = new Promise(resolve => {
  fetchA(a => resolve(a));
});

Given a reference to `promiseForA`, there's no way to call `fetchA`
again. Calling `then` on the promise doesn't run the constructor again;
it only attaches another listener.

In the future we will likely introduce an API like `React.eager` that
is similar to `lazy` but eagerly calls the constructor. That gives us
the ability to call the constructor multiple times. E.g. to increase
the priority, or to retry if the first operation failed.
2018-10-18 19:57:12 -07:00