Commit Graph

10741 Commits

Author SHA1 Message Date
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
Andrew Clark d926936f0b Eager bailout optimization should always compare to latest reducer (#15124)
* Eager bailout optimization should always compare to latest reducer

* queue.eagerReducer -> queue.lastRenderedReducer

This name is a bit more descriptive.

* Add test case that uses preceding render phase update
2019-03-15 19:03:59 -07:00
Sebastian Markbåge 4162f6026c Add feature flag to disable yielding (#15119) 2019-03-15 15:54:22 -07:00
Dan Abramov 8d60bd4dc2 [Shallow] Implement setState for Hooks and remount on type change (#15120)
* Throw away old shallow renderer state on type change

This worked in function components but was broken for classes. It incorrectly retained the old instance even if the type was different.

* Remove _previousComponentIdentity

We only needed this because we didn't correctly reset based on type. Now we do so this can go away.

* Use _reset when unmounting

* Use arbitrary componentIdentity

There was no particular reason it was set to element.type. We just wanted to check if something is a render phase update.

* Support Hook state updates in shallow renderer
2019-03-15 22:30:32 +00:00
Dominic Gannaway 035e4cffbd Change passive checker to use defineProperty (#15121) 2019-03-15 22:24:25 +00:00
Brandon Dail b283d75c17 Support React.memo in ReactShallowRenderer (#14816)
* Support React.memo in ReactShallowRenderer

ReactShallowRenderer uses element.type frequently, but with React.memo
elements the actual type is element.type.type. This updates
ReactShallowRenderer so it uses the correct element type for Memo
components and also validates the inner props for the wrapped
components.

* Allow Rect.memo to prevent re-renders

* Support memo(forwardRef())

* Dont call memo comparison function on initial render

* Fix test

* Small tweaks
2019-03-15 22:17:09 +00:00
Dan Abramov f0621fe232 Use same example code for async effect warning (#15118) 2019-03-15 19:27:55 +00:00
Kayla Ngan ff4fb6d368 Remove facts tracker (#15111)
* Removed Travis references

* Remove used facts tracker
2019-03-15 19:25:06 +00:00
Sebastian Silbermann 52c870c8d9 Fix shallow renderer not allowing hooks in forwardRef render functions (#15100)
* test: Add test for shallow + forwardRef + hook

* fix(react-test-renderer): shallow forwardRef hooks
2019-03-15 15:28:34 +00:00
Dan Abramov f1ff4348c1 Don't suggest a function as its own dep (#15115) 2019-03-15 15:14:01 +00:00
Dominic Gannaway 371bbf36bb Add infrastructure for passive/non-passive event support for future API exploration (#15036)
* Add infrastructure for passive/non-passive event support for future event API experimentation
2019-03-15 09:39:43 +00:00
Mateusz ab5fe174c6 Don't set the first option as selected in select tag with size attribute (#14242)
* Set 'size' attribute to select tag if it occurs before appending options

* Add comment about why size is assigned on select create. Tests

I added some more clarification for why size must be set on select
element creation:

- In the source code
- In the DOM test fixture
- In a unit test

* Use let, not const in select tag stub assignment
2019-03-14 14:40:09 -07:00
Dan Abramov 935f60083f eslint-plugin-react-hooks@1.5.1 2019-03-14 20:11:22 +00:00
Dominic Gannaway 0c03a47436 Adds experimental event API scaffolding (#15108)
* Adds experimental event API scaffolding
2019-03-14 17:02:42 +00:00
Nathan Hunzaker 679402a66b Improve hydration fixture, support older versions of React (#14118)
* Hydration Fixture: Only load ReactDOMServer if it exists

Fixes an issue where the hydration fixture would try to load in
ReactDOMServer below version 14. In version 13, string markup methods
exist on the React namespace.

* DOM Fixtures: Use class component for App.js

This was breaking React 0.13.0.

* Hydration Fixture: better findDOMNode compatibility

This commit fixes an issue where the Hydration DOM fixture was
unusable in React 0.13.0 or lower because of newer API usage.

It fixes that by avoiding the use of refs to get the textarea
reference in the code editor component, using various versions of
findDOMNode as required.

* Hydration Fixture: Do not show dropdown for single-line errors

If an error showed for the hydration fixture, a detail element was
used even if no additional lines could display. In that case, this
commit changes the component such that it returns a div.

* Deeper React version support for hydration fixture

This commit adds support for versions 0.4.0 of React and higher for
the hydration fixture.

The DOM test fixtures themselves do not support down to React 0.4.0,
which would be exhaustive. Instead, the Hydration fixture can pick a
version to use for its own purposes. By default, this is the version
of React used by the fixtures.

In the process of doing this, I had to make some updates to the
renderer.html document associated with the hydration fixture, and I've
added some comments to better document the history of API changes.
2019-03-13 15:12:49 -07:00
Sophie Alpert 1204c78977 [eslint] Wording tweaks (#15078)
* [eslint] Wording tweaks

I think these are a little clearer.

* fix tests
2019-03-13 18:31:39 +00:00
Dan Abramov 9d77a317bf Improve async useEffect warning (#15104) 2019-03-13 16:20:13 +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 5d0c3c6c7d [Partial Hydration] Render client-only content at normal priority (#15061)
* Split props changing from permanent fallback state

These will need different logic. In this commit, no logic has changed,
only moved.

* Delete terminal fallback content in first pass

If the dehydrated suspense boundary's fallback content is terminal there
is nothing to show. We need to get actual content on the screen soon.

If we deprioritize that work to offscreen, then the timeout heuristics will
be wrong.

Therefore, if we have no current and we're already at terminal fallback
state we'll immediately schedule a deletion and upgrade to real suspense.

* Show failing case when there is another wrapper boundary

* Revert "Delete terminal fallback content in first pass"

This reverts commit ad67ba8928.

* Use the new approach of leaving work at normal pri to replace fallback
2019-03-11 13:50:19 -07:00
Andrew Clark 6a4a261ee8 Test suspended children are hidden before layout in persistent mode (#15030)
Refs behave differently in persistent mode, so instead of a ref, the
persistent mode version of this test asserts on the output of the
host tree.
2019-03-11 11:19:20 -07:00
Andrew Clark bc8bd24c14 Run persistent mode tests in CI (#15029)
* Add command to run tests in persistent mode

* Convert Suspense fuzz tester to use noop renderer

So we can run it in persistent mode, too.

* Don't mutate stateNode in appendAllChildren

We can't mutate the stateNode in appendAllChildren because the children
could be current.

This is a bit weird because now the child that we append is different
from the one on the fiber stateNode. I think this makes conceptual
sense, but I suspect this likely breaks an assumption in Fabric.

With this approach, we no longer need to clone to unhide the children,
so I removed those host config methods.

Fixes bug surfaced by fuzz tester. (The test case that failed was the
one that's already hard coded.)

* In persistent mode, disable test that reads a ref

Refs behave differently in persistent mode. I added a TODO to write
a persistent mode version of this test.

* Run persistent mode tests in CI

* test-persistent should skip files without noop

If a file doesn't reference react-noop-renderer, we shouldn't bother
running it in persistent mode, since the results will be identical to
the normal test run.

* Remove module constructor from placeholder tests

We don't need this now that we have the ability to run any test file in
either mutation or persistent mode.

* Revert "test-persistent should skip files without noop"

Seb objected to adding shelljs as a dep and I'm too lazy to worry about
Windows support so whatever I'll just revert this.

* Delete duplicate file
2019-03-11 10:56:34 -07:00
Andrew Clark 3f4852fa5f Run Placeholder tests in persistent mode, too (#15013)
* Convert ReactSuspensePlaceholder tests to use noop

Instead of the test renderer, since test renderer does not support
running in persistent mode.

* Run Placeholder tests in persistent mode, too

* Fix Flow and lint

* Hidden text instances should have correct host context

Adds a test for a subtle edge case that only occurs in persistent mode.

* createHiddenTextInstance -> cloneHiddenTextInstance

This sidesteps the problem where createHiddenTextInstance needs access
to the host context.
2019-03-08 18:53:14 -08:00
Dan Abramov d0289c7e3a eslint-plugin-react-hooks@1.5.0 2019-03-07 19:43:07 +00:00
Dan Abramov 03ad9c73e4 [ESLint] Tweak setState updater message and add useEffect(async) warning (#15055)
* Use first letter in setCount(c => ...) suggestion

In-person testing showed using original variable name confuses people.

* Warn about async effects
2019-03-07 19:40:23 +00:00
Dan Abramov eb6247a9ab More concise messages (#15053) 2019-03-07 15:21:44 +00:00
Dan Abramov 197703ecc7 [ESLint] Add more hints to lint messages (#15046)
* A clearer message for props destructuring where applicable

* Add line number to the "move function" message

* Add a hint for how to fix callbacks from props

* Simplify code and harden tests

* Collect all dependency references for better warnings

* Suggest updater or reducer where appropriate
2019-03-07 12:39:15 +00:00
Dan Abramov 6d2666bab1 Fix ESLint rule crash (#15044) 2019-03-07 00:39:39 +00:00
Dan Abramov 9b7e1d1389 [ESLint] Suggest moving inside a Hook or useCallback when bare function is a dependency (#15026)
* Warn about bare function deps and suggest moving or useCallback

* Clearer wording
2019-03-06 23:50:02 +00:00
Andrew Clark 1e3b6192b5 Import Scheduler directly, not via host config (#14984)
* Import Scheduler directly, not via host config

We currently schedule asynchronous tasks via the host config. (The host
config is a static/build-time dependency injection system that varies
across different renderers — DOM, native, test, and so on.) Instead of
calling platform APIs like `requestIdleCallback` directly, each renderer
implements a method called `scheduleDeferredCallback`.

We've since discovered that when scheduling tasks, it's crucial that
React work is placed in the same queue as other, non-React work on the
main thread. Otherwise, you easily end up in a starvation scenario where
rendering is constantly interrupted by less important tasks. You need a
centralized coordinator that is used both by React and by other
frameworks and application code. This coordinator must also have a
consistent API across all the different host environments, for
convention's sake and so product code is portable — e.g. so the same
component can work in both React Native and React Native Web.

This turned into the Scheduler package. We will have different builds of
Scheduler for each of our target platforms. With this approach, we treat
Scheduler like a built-in platform primitive that exists wherever React
is supported.

Now that we have this consistent interface, the indirection of the host
config no longer makes sense for the purpose of scheduling tasks. In
fact, we explicitly do not want renderers to scheduled task via any
system except the Scheduler package.

So, this PR removes `scheduleDeferredCallback` and its associated
methods from the host config in favor of directly importing Scheduler.

* Missed an extraneous export
2019-03-06 14:41:45 -08:00
Dan Abramov 5d49dafac8 Enforce deps array in useMemo and useCallback (#15025) 2019-03-06 18:17:54 +00:00
Brian Vaughn a9aa24ed8d 16.8.4 and changelog 2019-03-05 15:17:42 -08:00
Dan Abramov db8d466554 Fix heading in changelog 2019-03-05 22:40:04 +00:00
Dan Abramov fa5d4ee43b [ESLint] Treat functions that don't capture anything as static (#14996)
* Treat functions that don't capture anything as static

* Fix comment
2019-03-05 21:07:37 +00:00
Dan Abramov fd557d453d Warn on mount when deps are not an array (#15018)
* Warn on mount when deps are not an array

* Check other Hooks

* I can't figure out how to fix error/warning nesting lint

But it doesn't really matter much because we test other cases in the other test.
2019-03-05 17:41:27 +00:00
Farhad Yasir ff596e3efb fix(auto-version-update): update root package version while publishing (#15005)
* fix(auto-version-update): update root package version while publishing

* fix(remove-version): remove version field from package json
2019-03-04 12:36:17 -08:00
Andrew Clark ce45ca9ba3 Prettier 2019-03-04 11:38:08 -08:00
Andrew Clark 757a70b25d ReactNoop.yield -> Scheduler.yieldValue (#15008)
These used to be different things, but now ReactNoop.yield merely
re-exports Scheduler.yieldValue, so let's get rid of it.
2019-03-04 11:23:00 -08:00
Andrew Clark 9d756d903f Revert #14756 changes to ReactFiberScheduler (#14992)
* Revert #14756 changes to ReactFiberScheduler

This PR introduced some bugs in concurrent mode during internal testing.
Until we figure out a proper solution, I'm going to try reverting it.

Not totally certain this is sufficient to unbreak the bugs we found, but
I'm using this branch to determine that.

* Add back commented out Scheduler import

With a note not to use named imports next time we import Scheduler
in this module.
2019-03-01 13:10:12 -08:00
Dan Abramov f16442a106 eslint-plugin-react-hooks@1.4.0 2019-03-01 20:29:06 +00:00
Dan Abramov e1e45fb367 [ESLint] Suggest to destructure props when they are only used as members (#14993)
* Suggest to destructure props when they are only used as members

* Add more tests

* Fix a bug
2019-03-01 19:48:48 +00:00
Dan Abramov 59ef28437a Warn about dependencies outside of render scope (#14990) 2019-03-01 18:16:17 +00:00
Dan Abramov df7b4768c7 [ESLint] Deduplicate suggested dependencies (#14982)
* Deduplicate suggested dependencies

* Tweak test cases
2019-03-01 16:10:22 +00:00
Dan Abramov 02404d793b Avoid dynamic dispatch for scheduler calls (#14968) 2019-03-01 15:04:15 +00:00
Brian Vaughn bb2939ccc2 Support editable useState hooks in DevTools (#14906)
* ReactDebugHooks identifies State and Reducer hooks as editable
* Inject overrideHookState() method to DevTools to support editing in DEV builds
* Added an integration test for React DevTools, react-debug-tools, and overrideHookState
2019-02-28 14:37:55 -08:00
Andrew Clark 69060e1da6 Swap expect(ReactNoop) for expect(Scheduler) (#14971)
* Swap expect(ReactNoop) for expect(Scheduler)

In the previous commits, I upgraded our custom Jest matchers for the
noop and test renderers to use Scheduler under the hood.

Now that all these matchers are using Scheduler, we can drop
support for passing ReactNoop and test roots and always pass
Scheduler directly.

* Externalize Scheduler in noop and test bundles

I also noticed we don't need to regenerator runtime in noop anymore.
2019-02-28 12:54:47 -08:00
Andrew Clark ccb2a8a44e Replace test renderer's fake Scheduler implementation with mock build (#14970)
* Replace test renderer's fake Scheduler implementation with mock build

The test renderer has its own mock implementation of the Scheduler
interface, with the ability to partially render work in tests. Now that
this functionality has been lifted into a proper mock Scheduler build,
we can use that instead.

* Fix Profiler tests in prod
2019-02-28 10:50:38 -08:00
Andrew Clark 53e787b45f Replace noop's fake Scheduler implementation with mock Scheduler build (#14969)
* Replace noop's fake Scheduler implementation with mock Scheduler build

The noop renderer has its own mock implementation of the Scheduler
interface, with the ability to partially render work in tests. Now that
this functionality has been lifted into a proper mock Scheduler build,
we can use that instead.

Most of the existing noop tests were unaffected, but I did have to make
some changes. The biggest one involved passive effects: previously, they
were scheduled on a separate queue from the queue that handles
rendering. After this change, both rendering and effects are scheduled
in the Scheduler queue. I think this is a better approach because tests
no longer have to worry about the difference; if you call `flushAll`,
all the work is flushed, both rendering and effects. But for those few
tests that do care to flush the rendering without the effects, that's
still possible using the `yieldValue` API.

Follow-up: Do the same for test renderer.

* Fix import to scheduler/unstable_mock
2019-02-28 10:30:46 -08:00
Dan Abramov 3ada82b741 Allow extraneous effect dependencies (#14967)
This makes cases like

  useEffect(() => {
    window.scrollTo(0, 0);
  }, [activeTab]);

not warn.

However, it still warns for unused useCallback/useMemo deps.
2019-02-27 16:59:11 +00:00
Andrew Clark 00748c53e1 Add new mock build of Scheduler with flush, yield API (#14964)
* Add new mock build of Scheduler with flush, yield API

Test environments need a way to take control of the Scheduler queue and
incrementally flush work. Our current tests accomplish this either using
dynamic injection, or by using Jest's fake timers feature. Both of these
options are fragile and rely too much on implementation details.

In this new approach, we have a separate build of Scheduler that is
specifically designed for test environments. We mock the default
implementation like we would any other module; in our case, via Jest.
This special build has methods like `flushAll` and `yieldValue` that
control when work is flushed. These methods are based on equivalent
methods we've been using to write incremental React tests. Eventually
we may want to migrate the React tests to interact with the mock
Scheduler directly, instead of going through the host config like we
currently do.

For now, I'm using our custom static injection infrastructure to create
the two builds of Scheduler — a default build for DOM (which falls back
to a naive timer based implementation), and the new mock build. I did it
this way because it allows me to share most of the implementation, which
isn't specific to a host environment — e.g. everything related to the
priority queue. It may be better to duplicate the shared code instead,
especially considering that future environments (like React Native) may
have entirely forked implementations. I'd prefer to wait until the
implementation stabilizes before worrying about that, but I'm open to
changing this now if we decide it's important enough.

* Mock Scheduler in bundle tests, too

* Remove special case by making regex more restrictive
2019-02-26 20:51:17 -08:00
Brian Vaughn 4186952a6f Fixed incompatibility between react-debug-tools and useContext() (#14940)
* Refactor hook ordering check to use DEV-only data structure. This enables us to warn about more cases (e.g. useContext, useDebugValue) withou the need to add any overhead to production bundles.
2019-02-26 14:24:52 -08:00