-
Notifications
You must be signed in to change notification settings - Fork 47.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Set owner correctly inside forwardRef and context consumer #12777
Conversation
Does the debug thing need to be wrapped in DEV? |
Yeah, you're right. |
b2cd16a
to
2fed93d
Compare
Details of bundled changes.Comparing: a9abd27...e8394da react-dom
react-art
react-test-renderer
react-reconciler
react-native-renderer
Generated by 🚫 dangerJS |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These changes appear to be appropriately amended...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
looks good, lets try it out...
Previously, _owner would be null if you create an element inside forwardRef or inside a context consumer. This is used by ReactNativeFiberInspector when traversing the hierarchy and also to give more info in some warning texts. This also means you'll now correctly get a warning if you call setState inside one of these. Test Plan: Tim tried it in the RN inspector.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Awesome. Thanks for fixing this so quickly.
|
||
let nextChildren; | ||
if (__DEV__) { | ||
ReactCurrentOwner.current = workInProgress; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This doesn't look right. We shouldn't set current owner, which is runtime behavior, only in DEV. This could mess up certain new features in prod for example.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We were supposed to use the debug frame thing for DEV warnings instead of owner so that we didn't have to do this. Perhaps the fix is to change how the context warning works so that it doesn't rely on current owner? @acdlite
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
oh hm. for functional and indeterminate components it looks DEV-only:
react/packages/react-reconciler/src/ReactFiberBeginWork.js
Lines 260 to 344 in e8394da
ReactCurrentOwner.current = workInProgress; | |
ReactDebugCurrentFiber.setCurrentPhase('render'); | |
nextChildren = fn(nextProps, context); | |
ReactDebugCurrentFiber.setCurrentPhase(null); | |
} else { | |
nextChildren = fn(nextProps, context); | |
} | |
// React DevTools reads this flag. | |
workInProgress.effectTag |= PerformedWork; | |
reconcileChildren(current, workInProgress, nextChildren); | |
memoizeProps(workInProgress, nextProps); | |
return workInProgress.child; | |
} | |
function updateClassComponent( | |
current: Fiber | null, | |
workInProgress: Fiber, | |
renderExpirationTime: ExpirationTime, | |
) { | |
// Push context providers early to prevent context stack mismatches. | |
// During mounting we don't know the child context yet as the instance doesn't exist. | |
// We will invalidate the child context in finishClassComponent() right after rendering. | |
const hasContext = pushLegacyContextProvider(workInProgress); | |
let shouldUpdate; | |
if (current === null) { | |
if (workInProgress.stateNode === null) { | |
// In the initial pass we might need to construct the instance. | |
constructClassInstance( | |
workInProgress, | |
workInProgress.pendingProps, | |
renderExpirationTime, | |
); | |
mountClassInstance(workInProgress, renderExpirationTime); | |
shouldUpdate = true; | |
} else { | |
// In a resume, we'll already have an instance we can reuse. | |
shouldUpdate = resumeMountClassInstance( | |
workInProgress, | |
renderExpirationTime, | |
); | |
} | |
} else { | |
shouldUpdate = updateClassInstance( | |
current, | |
workInProgress, | |
renderExpirationTime, | |
); | |
} | |
return finishClassComponent( | |
current, | |
workInProgress, | |
shouldUpdate, | |
hasContext, | |
renderExpirationTime, | |
); | |
} | |
function finishClassComponent( | |
current: Fiber | null, | |
workInProgress: Fiber, | |
shouldUpdate: boolean, | |
hasContext: boolean, | |
renderExpirationTime: ExpirationTime, | |
) { | |
// Refs should update even if shouldComponentUpdate returns false | |
markRef(current, workInProgress); | |
const didCaptureError = | |
(workInProgress.effectTag & DidCapture) !== NoEffect; | |
if (!shouldUpdate && !didCaptureError) { | |
// Context providers should defer to sCU for rendering | |
if (hasContext) { | |
invalidateContextProvider(workInProgress, false); | |
} | |
return bailoutOnAlreadyFinishedWork(current, workInProgress); | |
} | |
const ctor = workInProgress.type; | |
const instance = workInProgress.stateNode; | |
// Rerender | |
ReactCurrentOwner.current = workInProgress; |
I guess that's an oversight?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think at the time this was intentional because we didn't separate those concepts, and didn't want to have the overhead of setting a property in PROD when it doesn't end up being used (functional components can't be ref owners which was the only runtime behavior of this feature).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We just have to be better at following through when we change strategies like introducing debug frame.
20: Update react monorepo to v16.4.0 r=renovate[bot] a=renovate[bot] This Pull Request renovates the package group "react monorepo". - [react-dom](https://github.com/facebook/react) (`dependencies`): from `16.3.2` to `16.4.0` - [react](https://github.com/facebook/react) (`dependencies`): from `16.3.2` to `16.4.0` # Release Notes <details> <summary>facebook/react</summary> ### [`v16.4.0`](https://github.com/facebook/react/blob/master/CHANGELOG.md#​1640-May-23-2018) [Compare Source](facebook/react@8e5f12c...v16.4.0) ##### React * Add a new [experimental](`https://github.com/reactjs/rfcs/pull/51`) `React.unstable_Profiler` component for measuring performance. ([@​bvaughn] in [#​12745](`https://github.com/facebook/react/pull/12745`)) ##### React DOM * Add support for the Pointer Events specification. ([@​philipp-spiess] in [#​12507](`https://github.com/facebook/react/pull/12507`)) * Properly call `getDerivedStateFromProps()` regardless of the reason for re-rendering. ([@​acdlite] in [#​12600](`https://github.com/facebook/react/pull/12600`) and [#​12802](`https://github.com/facebook/react/pull/12802`)) * Fix a bug that prevented context propagation in some cases. ([@​gaearon] in [#​12708](`https://github.com/facebook/react/pull/12708`)) * Fix re-rendering of components using `forwardRef()` on a deeper `setState()`. ([@​gaearon] in [#​12690](`https://github.com/facebook/react/pull/12690`)) * Fix some attributes incorrectly getting removed from custom element nodes. ([@​airamrguez] in [#​12702](`https://github.com/facebook/react/pull/12702`)) * Fix context providers to not bail out on children if there's a legacy context provider above. ([@​gaearon] in [#​12586](`https://github.com/facebook/react/pull/12586`)) * Add the ability to specify `propTypes` on a context provider component. ([@​nicolevy] in [#​12658](`https://github.com/facebook/react/pull/12658`)) * Fix a false positive warning when using `react-lifecycles-compat` in `<StrictMode>`. ([@​bvaughn] in [#​12644](`https://github.com/facebook/react/pull/12644`)) * Warn when the `forwardRef()` render function has `propTypes` or `defaultProps`. ([@​bvaughn] in [#​12644](`https://github.com/facebook/react/pull/12644`)) * Improve how `forwardRef()` and context consumers are displayed in the component stack. ([@​sophiebits] in [#​12777](`https://github.com/facebook/react/pull/12777`)) * Change internal event names. This can break third-party packages that rely on React internals in unsupported ways. ([@​philipp-spiess] in [#​12629](`https://github.com/facebook/react/pull/12629`)) ##### React Test Renderer * Fix the `getDerivedStateFromProps()` support to match the new React DOM behavior. ([@​koba04] in [#​12676](`https://github.com/facebook/react/pull/12676`)) * Fix a `testInstance.parent` crash when the parent is a fragment or another special node. ([@​gaearon] in [#​12813](`https://github.com/facebook/react/pull/12813`)) * `forwardRef()` components are now discoverable by the test renderer traversal methods. ([@​gaearon] in [#​12725](`https://github.com/facebook/react/pull/12725`)) * Shallow renderer now ignores `setState()` updaters that return `null` or `undefined`. ([@​koba04] in [#​12756](`https://github.com/facebook/react/pull/12756`)) ##### React ART * Fix reading context provided from the tree managed by React DOM. ([@​acdlite] in [#​12779](`https://github.com/facebook/react/pull/12779`)) ##### React Call Return (Experimental) * This experiment was deleted because it was affecting the bundle size and the API wasn't good enough. It's likely to come back in the future in some other form. ([@​gaearon] in [#​12820](`https://github.com/facebook/react/pull/12820`)) ##### React Reconciler (Experimental) * The [new host config shape](https://github.com/facebook/react/blob/c601f7a64640290af85c9f0e33c78480656b46bc/packages/react-noop-renderer/src/createReactNoop.js#L82-L285) is flat and doesn't use nested objects. ([@​gaearon] in [#​12792](`https://github.com/facebook/react/pull/12792`)) --- </details> --- This PR has been generated by [Renovate Bot](https://renovatebot.com). Co-authored-by: Renovate Bot <bot@renovateapp.com>
164: Update react monorepo to v16.4.0 r=rehandalal a=renovate[bot] This Pull Request renovates the package group "react monorepo". - [react-dom](https://github.com/facebook/react) (`dependencies`): from `16.3.2` to `16.4.0` - [react](https://github.com/facebook/react) (`dependencies`): from `16.3.2` to `16.4.0` # Release Notes <details> <summary>facebook/react</summary> ### [`v16.4.0`](https://github.com/facebook/react/blob/master/CHANGELOG.md#​1640-May-23-2018) [Compare Source](facebook/react@8e5f12c...v16.4.0) ##### React * Add a new [experimental](`https://github.com/reactjs/rfcs/pull/51`) `React.unstable_Profiler` component for measuring performance. ([@​bvaughn] in [#​12745](`https://github.com/facebook/react/pull/12745`)) ##### React DOM * Add support for the Pointer Events specification. ([@​philipp-spiess] in [#​12507](`https://github.com/facebook/react/pull/12507`)) * Properly call `getDerivedStateFromProps()` regardless of the reason for re-rendering. ([@​acdlite] in [#​12600](`https://github.com/facebook/react/pull/12600`) and [#​12802](`https://github.com/facebook/react/pull/12802`)) * Fix a bug that prevented context propagation in some cases. ([@​gaearon] in [#​12708](`https://github.com/facebook/react/pull/12708`)) * Fix re-rendering of components using `forwardRef()` on a deeper `setState()`. ([@​gaearon] in [#​12690](`https://github.com/facebook/react/pull/12690`)) * Fix some attributes incorrectly getting removed from custom element nodes. ([@​airamrguez] in [#​12702](`https://github.com/facebook/react/pull/12702`)) * Fix context providers to not bail out on children if there's a legacy context provider above. ([@​gaearon] in [#​12586](`https://github.com/facebook/react/pull/12586`)) * Add the ability to specify `propTypes` on a context provider component. ([@​nicolevy] in [#​12658](`https://github.com/facebook/react/pull/12658`)) * Fix a false positive warning when using `react-lifecycles-compat` in `<StrictMode>`. ([@​bvaughn] in [#​12644](`https://github.com/facebook/react/pull/12644`)) * Warn when the `forwardRef()` render function has `propTypes` or `defaultProps`. ([@​bvaughn] in [#​12644](`https://github.com/facebook/react/pull/12644`)) * Improve how `forwardRef()` and context consumers are displayed in the component stack. ([@​sophiebits] in [#​12777](`https://github.com/facebook/react/pull/12777`)) * Change internal event names. This can break third-party packages that rely on React internals in unsupported ways. ([@​philipp-spiess] in [#​12629](`https://github.com/facebook/react/pull/12629`)) ##### React Test Renderer * Fix the `getDerivedStateFromProps()` support to match the new React DOM behavior. ([@​koba04] in [#​12676](`https://github.com/facebook/react/pull/12676`)) * Fix a `testInstance.parent` crash when the parent is a fragment or another special node. ([@​gaearon] in [#​12813](`https://github.com/facebook/react/pull/12813`)) * `forwardRef()` components are now discoverable by the test renderer traversal methods. ([@​gaearon] in [#​12725](`https://github.com/facebook/react/pull/12725`)) * Shallow renderer now ignores `setState()` updaters that return `null` or `undefined`. ([@​koba04] in [#​12756](`https://github.com/facebook/react/pull/12756`)) ##### React ART * Fix reading context provided from the tree managed by React DOM. ([@​acdlite] in [#​12779](`https://github.com/facebook/react/pull/12779`)) ##### React Call Return (Experimental) * This experiment was deleted because it was affecting the bundle size and the API wasn't good enough. It's likely to come back in the future in some other form. ([@​gaearon] in [#​12820](`https://github.com/facebook/react/pull/12820`)) ##### React Reconciler (Experimental) * The [new host config shape](https://github.com/facebook/react/blob/c601f7a64640290af85c9f0e33c78480656b46bc/packages/react-noop-renderer/src/createReactNoop.js#L82-L285) is flat and doesn't use nested objects. ([@​gaearon] in [#​12792](`https://github.com/facebook/react/pull/12792`)) --- </details> --- This PR has been generated by [Renovate Bot](https://renovatebot.com). Co-authored-by: Renovate Bot <bot@renovateapp.com>
Previously, _owner would be null if you create an element inside forwardRef or inside a context consumer. This is used by ReactNativeFiberInspector when traversing the hierarchy and also to give more info in some warning texts. This also means you'll now correctly get a warning if you call setState inside one of these.
Test Plan: Tim tried it in the RN inspector.