Skip to content

[autodeps] Do not include nonreactive refs or setStates in inferred deps#32236

Merged
jbrown215 merged 4 commits into
facebook:mainfrom
jbrown215:pr32236
Mar 3, 2025
Merged

[autodeps] Do not include nonreactive refs or setStates in inferred deps#32236
jbrown215 merged 4 commits into
facebook:mainfrom
jbrown215:pr32236

Conversation

@jbrown215
Copy link
Copy Markdown
Contributor

@jbrown215 jbrown215 commented Jan 27, 2025

// If it is reactive OR it is not reactive and neither a ref or setState call, then we need to add it to the deps array
if (
reactiveIds.has(dep.identifier.id) ||
(!isUseRefType(dep.identifier) && !isSetStateType(dep.identifier))
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reactivity inference should already account for these types, why do we need to check them here? Note that you could still have a ref or state setter that is conditional on some other reactive value.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@josephsavona We can't prune purely based on reactivity inference (see above comment and infer-effect-deps/pruned-nonreactive-obj

I think we have 4 cases here. On one axis, there's reactivity (per data-flow analysis pre scope creation and merging/pruning)

Reactive Non reactive
hook return value dep ✅ not dep 🚫
other value dep ✅ might be dep if included into a reactive scope❓

@jbrown215 do you think it's easier to reason about this when excluding the (isUseRef || isSetState) && !reactive case, e.g.

for (const dep of scopeInfo.deps) {
  if ((isUseRef(dep.identifier) || isSetState(dep.identifier) && !reactiveIds.has(dep.identifier.id) {
    // exclude non-reactive hook results, which will never be in a memo block
    continue;
  }
  ...
}

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That version of it looks good to me! Getting this condition right was pretty tricky.

} else {
t0 = $[3];
}
useEffect(t0, [ref]);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice!

Copy link
Copy Markdown
Contributor

@mofeiZ mofeiZ left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Makes sense!

Summary: Summary: Correctly supports React.useEffect when React is imported as `import * as React from 'react'`
(as well as other namespaces as specified in the config).

Test Plan:
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

CLA Signed React Core Team Opened by a member of the React Core Team

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants