feat(client components): add use client directive at the top of files having client components - #4738

Merged
Ephem merged 9 commits into
TanStack:mainfrom
girishsontakke:issue-4689
Jan 24, 2023
Merged

feat(client components): add use client directive at the top of files having client components#4738
Ephem merged 9 commits into
TanStack:mainfrom
girishsontakke:issue-4689

Conversation

@girishsontakke

Copy link
Copy Markdown
Contributor

This PR is addressing the improvement suggested in #4689.

@codesandbox-ci

codesandbox-ciBot commented Jan 2, 2023

Copy link
Copy Markdown

This pull request is automatically built and testable in CodeSandbox.

To see build info of the built libraries, click here or the icon next to each commit SHA.

Latest deployment of this branch, based on commit a28c5a0:

SandboxSource
@tanstack/query-example-react-basic-typescriptConfiguration
@tanstack/query-example-solid-basic-typescriptConfiguration
@tanstack/query-example-svelte-basicConfiguration
@tanstack/query-example-vue-basicConfiguration

@TkDodoTkDodo left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Thanks. I think there are still a couple of places missing like:

  • useIsFetching
  • useIsMutating
  • the devtools
  • the react-query-persist package

@TkDodo

Copy link
Copy Markdown
Collaborator

not sure where all the conflicts are coming from. can you update with main once more please?

@girishsontakke

girishsontakke commented Jan 14, 2023

Copy link
Copy Markdown
ContributorAuthor

not sure where all the conflicts are coming from. can you update with main once more please?

Sure, I have removed the conflicts.

@codecov-commenter

codecov-commenter commented Jan 14, 2023

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 91.25%. Comparing base (eab6e2c) to head (a28c5a0).
⚠️ Report is 2966 commits behind head on main.

❗ There is a different number of reports uploaded between BASE (eab6e2c) and HEAD (a28c5a0). Click for more details.

HEAD has 2 uploads less than BASE
FlagBASE (eab6e2c)HEAD (a28c5a0)
31
Additional details and impacted files
@@ Coverage Diff @@## main #4738 +/- ##
==========================================
- Coverage 96.36% 91.25% -5.11% 
==========================================
Files 45 110 +65 Lines 2281 4116 +1835 Branches 640 1057 +417 ==========================================
+ Hits 2198 3756 +1558 - Misses 80 339 +259 - Partials 3 21 +18 

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@TkDodoTkDodo left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

there are more things that should be client components. Basically, everything that uses state, effects or context needs to be a client component. I haven't looked at the full list, but:

  • hydrate.tsx is definitely a client component
  • isRestoring.tsx` has react context

@Ephem

Copy link
Copy Markdown
Collaborator

Thanks for working on this!

I finally got around to do some testing, and I actually think we should not include 'use client' at the top of hooks-only files. First of all, it doesn't really have an effect because the components that use the hooks still needs to include the directive.

Second, having it in the hooks-only files actually hurts in a sense. If you forget to add 'use client' to a component that uses one of these hooks (will be a very common mistake in userland), the default is that you get a nice error message from React:

image

But if you have 'use client' in the hooks file, you instead get an unreadable build error (I guess because the file is still removed from the SC-bundle):

image

@TkDodo I think this also means we might want to split any file that has both client components and hooks into two separate ones, like Hydrate.tsx and QueryClientProvider.tsx? So you can use the component as a client component, but still get a nice error message if you try to say use useQueryClient in a nested Server Component somewhere? I think for this PR it's probably fine to just do 'use client' at the top of those files and live with a bad worse error message for a while though, it's all pretty experimental anyway. 😄

@TkDodo

Copy link
Copy Markdown
Collaborator

I think this also means we might want to split any file that has both client components and hooks into two separate ones, like Hydrate.tsx and QueryClientProvider.tsx?

oh yeah, good idea. I think in v5 the Hydrate is no longer a problem because we have removed the hook already, but it makes sense for QueryClientProvider

@Ephem

Copy link
Copy Markdown
Collaborator

I took the liberty of removing the 'use client' from the hooks files again, but didn't split the files, I think we can do that later. I think isRestoring.tsx is another annoying candidate btw:

'use client'import*asReactfrom'react'constIsRestoringContext=React.createContext(false)exportconstuseIsRestoring=()=>React.useContext(IsRestoringContext)exportconstIsRestoringProvider=IsRestoringContext.Provider

Any such context/useContext pattern will need to be split into two files to get good error messages for the useContext part..

@EphemEphem changed the title perf(client components): added use client directive at the top of files having client componentsfeat(client components): add use client directive at the top of files having client componentsJan 24, 2023
@Ephem
Ephem merged commit f57c8dc into TanStack:mainJan 24, 2023
@girishsontakke
girishsontakke deleted the issue-4689 branch January 24, 2023 12:14
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants

@girishsontakke@TkDodo@codecov-commenter@Ephem
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

feat(client components): add use client directive at the top of files having client components - #4738

Merged
Ephem merged 9 commits into
TanStack:mainfrom
girishsontakke:issue-4689
Jan 24, 2023
Merged

feat(client components): add use client directive at the top of files having client components#4738
Ephem merged 9 commits into
TanStack:mainfrom
girishsontakke:issue-4689

Conversation

@girishsontakke

Copy link
Copy Markdown
Contributor

This PR is addressing the improvement suggested in #4689.

@codesandbox-ci

codesandbox-ciBot commented Jan 2, 2023

Copy link
Copy Markdown

This pull request is automatically built and testable in CodeSandbox.

To see build info of the built libraries, click here or the icon next to each commit SHA.

Latest deployment of this branch, based on commit a28c5a0:

SandboxSource
@tanstack/query-example-react-basic-typescriptConfiguration
@tanstack/query-example-solid-basic-typescriptConfiguration
@tanstack/query-example-svelte-basicConfiguration
@tanstack/query-example-vue-basicConfiguration

@TkDodoTkDodo left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Thanks. I think there are still a couple of places missing like:

  • useIsFetching
  • useIsMutating
  • the devtools
  • the react-query-persist package

@TkDodo

Copy link
Copy Markdown
Collaborator

not sure where all the conflicts are coming from. can you update with main once more please?

@girishsontakke

girishsontakke commented Jan 14, 2023

Copy link
Copy Markdown
ContributorAuthor

not sure where all the conflicts are coming from. can you update with main once more please?

Sure, I have removed the conflicts.

@codecov-commenter

codecov-commenter commented Jan 14, 2023

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 91.25%. Comparing base (eab6e2c) to head (a28c5a0).
⚠️ Report is 2966 commits behind head on main.

❗ There is a different number of reports uploaded between BASE (eab6e2c) and HEAD (a28c5a0). Click for more details.

HEAD has 2 uploads less than BASE
FlagBASE (eab6e2c)HEAD (a28c5a0)
31
Additional details and impacted files
@@ Coverage Diff @@## main #4738 +/- ##
==========================================
- Coverage 96.36% 91.25% -5.11% 
==========================================
Files 45 110 +65 Lines 2281 4116 +1835 Branches 640 1057 +417 ==========================================
+ Hits 2198 3756 +1558 - Misses 80 339 +259 - Partials 3 21 +18 

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@TkDodoTkDodo left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

there are more things that should be client components. Basically, everything that uses state, effects or context needs to be a client component. I haven't looked at the full list, but:

  • hydrate.tsx is definitely a client component
  • isRestoring.tsx` has react context

@Ephem

Copy link
Copy Markdown
Collaborator

Thanks for working on this!

I finally got around to do some testing, and I actually think we should not include 'use client' at the top of hooks-only files. First of all, it doesn't really have an effect because the components that use the hooks still needs to include the directive.

Second, having it in the hooks-only files actually hurts in a sense. If you forget to add 'use client' to a component that uses one of these hooks (will be a very common mistake in userland), the default is that you get a nice error message from React:

image

But if you have 'use client' in the hooks file, you instead get an unreadable build error (I guess because the file is still removed from the SC-bundle):

image

@TkDodo I think this also means we might want to split any file that has both client components and hooks into two separate ones, like Hydrate.tsx and QueryClientProvider.tsx? So you can use the component as a client component, but still get a nice error message if you try to say use useQueryClient in a nested Server Component somewhere? I think for this PR it's probably fine to just do 'use client' at the top of those files and live with a bad worse error message for a while though, it's all pretty experimental anyway. 😄

@TkDodo

Copy link
Copy Markdown
Collaborator

I think this also means we might want to split any file that has both client components and hooks into two separate ones, like Hydrate.tsx and QueryClientProvider.tsx?

oh yeah, good idea. I think in v5 the Hydrate is no longer a problem because we have removed the hook already, but it makes sense for QueryClientProvider

@Ephem

Copy link
Copy Markdown
Collaborator

I took the liberty of removing the 'use client' from the hooks files again, but didn't split the files, I think we can do that later. I think isRestoring.tsx is another annoying candidate btw:

'use client'import*asReactfrom'react'constIsRestoringContext=React.createContext(false)exportconstuseIsRestoring=()=>React.useContext(IsRestoringContext)exportconstIsRestoringProvider=IsRestoringContext.Provider

Any such context/useContext pattern will need to be split into two files to get good error messages for the useContext part..

@EphemEphem changed the title perf(client components): added use client directive at the top of files having client componentsfeat(client components): add use client directive at the top of files having client componentsJan 24, 2023
@Ephem
Ephem merged commit f57c8dc into TanStack:mainJan 24, 2023
@girishsontakke
girishsontakke deleted the issue-4689 branch January 24, 2023 12:14
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants

@girishsontakke@TkDodo@codecov-commenter@Ephem
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

feat(client components): add use client directive at the top of files having client components - #4738

Merged
Ephem merged 9 commits into
TanStack:mainfrom
girishsontakke:issue-4689
Jan 24, 2023
Merged

feat(client components): add use client directive at the top of files having client components#4738
Ephem merged 9 commits into
TanStack:mainfrom
girishsontakke:issue-4689

Conversation

@girishsontakke

Copy link
Copy Markdown
Contributor

This PR is addressing the improvement suggested in #4689.

@codesandbox-ci

codesandbox-ciBot commented Jan 2, 2023

Copy link
Copy Markdown

This pull request is automatically built and testable in CodeSandbox.

To see build info of the built libraries, click here or the icon next to each commit SHA.

Latest deployment of this branch, based on commit a28c5a0:

SandboxSource
@tanstack/query-example-react-basic-typescriptConfiguration
@tanstack/query-example-solid-basic-typescriptConfiguration
@tanstack/query-example-svelte-basicConfiguration
@tanstack/query-example-vue-basicConfiguration

@TkDodoTkDodo left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Thanks. I think there are still a couple of places missing like:

  • useIsFetching
  • useIsMutating
  • the devtools
  • the react-query-persist package

@TkDodo

Copy link
Copy Markdown
Collaborator

not sure where all the conflicts are coming from. can you update with main once more please?

@girishsontakke

girishsontakke commented Jan 14, 2023

Copy link
Copy Markdown
ContributorAuthor

not sure where all the conflicts are coming from. can you update with main once more please?

Sure, I have removed the conflicts.

@codecov-commenter

codecov-commenter commented Jan 14, 2023

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 91.25%. Comparing base (eab6e2c) to head (a28c5a0).
⚠️ Report is 2966 commits behind head on main.

❗ There is a different number of reports uploaded between BASE (eab6e2c) and HEAD (a28c5a0). Click for more details.

HEAD has 2 uploads less than BASE
FlagBASE (eab6e2c)HEAD (a28c5a0)
31
Additional details and impacted files
@@ Coverage Diff @@## main #4738 +/- ##
==========================================
- Coverage 96.36% 91.25% -5.11% 
==========================================
Files 45 110 +65 Lines 2281 4116 +1835 Branches 640 1057 +417 ==========================================
+ Hits 2198 3756 +1558 - Misses 80 339 +259 - Partials 3 21 +18 

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@TkDodoTkDodo left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

there are more things that should be client components. Basically, everything that uses state, effects or context needs to be a client component. I haven't looked at the full list, but:

  • hydrate.tsx is definitely a client component
  • isRestoring.tsx` has react context

@Ephem

Copy link
Copy Markdown
Collaborator

Thanks for working on this!

I finally got around to do some testing, and I actually think we should not include 'use client' at the top of hooks-only files. First of all, it doesn't really have an effect because the components that use the hooks still needs to include the directive.

Second, having it in the hooks-only files actually hurts in a sense. If you forget to add 'use client' to a component that uses one of these hooks (will be a very common mistake in userland), the default is that you get a nice error message from React:

image

But if you have 'use client' in the hooks file, you instead get an unreadable build error (I guess because the file is still removed from the SC-bundle):

image

@TkDodo I think this also means we might want to split any file that has both client components and hooks into two separate ones, like Hydrate.tsx and QueryClientProvider.tsx? So you can use the component as a client component, but still get a nice error message if you try to say use useQueryClient in a nested Server Component somewhere? I think for this PR it's probably fine to just do 'use client' at the top of those files and live with a bad worse error message for a while though, it's all pretty experimental anyway. 😄

@TkDodo

Copy link
Copy Markdown
Collaborator

I think this also means we might want to split any file that has both client components and hooks into two separate ones, like Hydrate.tsx and QueryClientProvider.tsx?

oh yeah, good idea. I think in v5 the Hydrate is no longer a problem because we have removed the hook already, but it makes sense for QueryClientProvider

@Ephem

Copy link
Copy Markdown
Collaborator

I took the liberty of removing the 'use client' from the hooks files again, but didn't split the files, I think we can do that later. I think isRestoring.tsx is another annoying candidate btw:

'use client'import*asReactfrom'react'constIsRestoringContext=React.createContext(false)exportconstuseIsRestoring=()=>React.useContext(IsRestoringContext)exportconstIsRestoringProvider=IsRestoringContext.Provider

Any such context/useContext pattern will need to be split into two files to get good error messages for the useContext part..

@EphemEphem changed the title perf(client components): added use client directive at the top of files having client componentsfeat(client components): add use client directive at the top of files having client componentsJan 24, 2023
@Ephem
Ephem merged commit f57c8dc into TanStack:mainJan 24, 2023
@girishsontakke
girishsontakke deleted the issue-4689 branch January 24, 2023 12:14
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants

@girishsontakke@TkDodo@codecov-commenter@Ephem
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

feat(client components): add use client directive at the top of files having client components - #4738

Merged
Ephem merged 9 commits into
TanStack:mainfrom
girishsontakke:issue-4689
Jan 24, 2023
Merged

feat(client components): add use client directive at the top of files having client components#4738
Ephem merged 9 commits into
TanStack:mainfrom
girishsontakke:issue-4689

Conversation

@girishsontakke

Copy link
Copy Markdown
Contributor

This PR is addressing the improvement suggested in #4689.

@codesandbox-ci

codesandbox-ciBot commented Jan 2, 2023

Copy link
Copy Markdown

This pull request is automatically built and testable in CodeSandbox.

To see build info of the built libraries, click here or the icon next to each commit SHA.

Latest deployment of this branch, based on commit a28c5a0:

SandboxSource
@tanstack/query-example-react-basic-typescriptConfiguration
@tanstack/query-example-solid-basic-typescriptConfiguration
@tanstack/query-example-svelte-basicConfiguration
@tanstack/query-example-vue-basicConfiguration

@TkDodoTkDodo left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Thanks. I think there are still a couple of places missing like:

  • useIsFetching
  • useIsMutating
  • the devtools
  • the react-query-persist package

@TkDodo

Copy link
Copy Markdown
Collaborator

not sure where all the conflicts are coming from. can you update with main once more please?

@girishsontakke

girishsontakke commented Jan 14, 2023

Copy link
Copy Markdown
ContributorAuthor

not sure where all the conflicts are coming from. can you update with main once more please?

Sure, I have removed the conflicts.

@codecov-commenter

codecov-commenter commented Jan 14, 2023

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 91.25%. Comparing base (eab6e2c) to head (a28c5a0).
⚠️ Report is 2966 commits behind head on main.

❗ There is a different number of reports uploaded between BASE (eab6e2c) and HEAD (a28c5a0). Click for more details.

HEAD has 2 uploads less than BASE
FlagBASE (eab6e2c)HEAD (a28c5a0)
31
Additional details and impacted files
@@ Coverage Diff @@## main #4738 +/- ##
==========================================
- Coverage 96.36% 91.25% -5.11% 
==========================================
Files 45 110 +65 Lines 2281 4116 +1835 Branches 640 1057 +417 ==========================================
+ Hits 2198 3756 +1558 - Misses 80 339 +259 - Partials 3 21 +18 

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@TkDodoTkDodo left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

there are more things that should be client components. Basically, everything that uses state, effects or context needs to be a client component. I haven't looked at the full list, but:

  • hydrate.tsx is definitely a client component
  • isRestoring.tsx` has react context

@Ephem

Copy link
Copy Markdown
Collaborator

Thanks for working on this!

I finally got around to do some testing, and I actually think we should not include 'use client' at the top of hooks-only files. First of all, it doesn't really have an effect because the components that use the hooks still needs to include the directive.

Second, having it in the hooks-only files actually hurts in a sense. If you forget to add 'use client' to a component that uses one of these hooks (will be a very common mistake in userland), the default is that you get a nice error message from React:

image

But if you have 'use client' in the hooks file, you instead get an unreadable build error (I guess because the file is still removed from the SC-bundle):

image

@TkDodo I think this also means we might want to split any file that has both client components and hooks into two separate ones, like Hydrate.tsx and QueryClientProvider.tsx? So you can use the component as a client component, but still get a nice error message if you try to say use useQueryClient in a nested Server Component somewhere? I think for this PR it's probably fine to just do 'use client' at the top of those files and live with a bad worse error message for a while though, it's all pretty experimental anyway. 😄

@TkDodo

Copy link
Copy Markdown
Collaborator

I think this also means we might want to split any file that has both client components and hooks into two separate ones, like Hydrate.tsx and QueryClientProvider.tsx?

oh yeah, good idea. I think in v5 the Hydrate is no longer a problem because we have removed the hook already, but it makes sense for QueryClientProvider

@Ephem

Copy link
Copy Markdown
Collaborator

I took the liberty of removing the 'use client' from the hooks files again, but didn't split the files, I think we can do that later. I think isRestoring.tsx is another annoying candidate btw:

'use client'import*asReactfrom'react'constIsRestoringContext=React.createContext(false)exportconstuseIsRestoring=()=>React.useContext(IsRestoringContext)exportconstIsRestoringProvider=IsRestoringContext.Provider

Any such context/useContext pattern will need to be split into two files to get good error messages for the useContext part..

@EphemEphem changed the title perf(client components): added use client directive at the top of files having client componentsfeat(client components): add use client directive at the top of files having client componentsJan 24, 2023
@Ephem
Ephem merged commit f57c8dc into TanStack:mainJan 24, 2023
@girishsontakke
girishsontakke deleted the issue-4689 branch January 24, 2023 12:14
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants

@girishsontakke@TkDodo@codecov-commenter@Ephem
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

feat(client components): add use client directive at the top of files having client components - #4738

Merged
Ephem merged 9 commits into
TanStack:mainfrom
girishsontakke:issue-4689
Jan 24, 2023
Merged

feat(client components): add use client directive at the top of files having client components#4738
Ephem merged 9 commits into
TanStack:mainfrom
girishsontakke:issue-4689

Conversation

@girishsontakke

Copy link
Copy Markdown
Contributor

This PR is addressing the improvement suggested in #4689.

@codesandbox-ci

codesandbox-ciBot commented Jan 2, 2023

Copy link
Copy Markdown

This pull request is automatically built and testable in CodeSandbox.

To see build info of the built libraries, click here or the icon next to each commit SHA.

Latest deployment of this branch, based on commit a28c5a0:

SandboxSource
@tanstack/query-example-react-basic-typescriptConfiguration
@tanstack/query-example-solid-basic-typescriptConfiguration
@tanstack/query-example-svelte-basicConfiguration
@tanstack/query-example-vue-basicConfiguration

@TkDodoTkDodo left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Thanks. I think there are still a couple of places missing like:

  • useIsFetching
  • useIsMutating
  • the devtools
  • the react-query-persist package

@TkDodo

Copy link
Copy Markdown
Collaborator

not sure where all the conflicts are coming from. can you update with main once more please?

@girishsontakke

girishsontakke commented Jan 14, 2023

Copy link
Copy Markdown
ContributorAuthor

not sure where all the conflicts are coming from. can you update with main once more please?

Sure, I have removed the conflicts.

@codecov-commenter

codecov-commenter commented Jan 14, 2023

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 91.25%. Comparing base (eab6e2c) to head (a28c5a0).
⚠️ Report is 2966 commits behind head on main.

❗ There is a different number of reports uploaded between BASE (eab6e2c) and HEAD (a28c5a0). Click for more details.

HEAD has 2 uploads less than BASE
FlagBASE (eab6e2c)HEAD (a28c5a0)
31
Additional details and impacted files
@@ Coverage Diff @@## main #4738 +/- ##
==========================================
- Coverage 96.36% 91.25% -5.11% 
==========================================
Files 45 110 +65 Lines 2281 4116 +1835 Branches 640 1057 +417 ==========================================
+ Hits 2198 3756 +1558 - Misses 80 339 +259 - Partials 3 21 +18 

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@TkDodoTkDodo left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

there are more things that should be client components. Basically, everything that uses state, effects or context needs to be a client component. I haven't looked at the full list, but:

  • hydrate.tsx is definitely a client component
  • isRestoring.tsx` has react context

@Ephem

Copy link
Copy Markdown
Collaborator

Thanks for working on this!

I finally got around to do some testing, and I actually think we should not include 'use client' at the top of hooks-only files. First of all, it doesn't really have an effect because the components that use the hooks still needs to include the directive.

Second, having it in the hooks-only files actually hurts in a sense. If you forget to add 'use client' to a component that uses one of these hooks (will be a very common mistake in userland), the default is that you get a nice error message from React:

image

But if you have 'use client' in the hooks file, you instead get an unreadable build error (I guess because the file is still removed from the SC-bundle):

image

@TkDodo I think this also means we might want to split any file that has both client components and hooks into two separate ones, like Hydrate.tsx and QueryClientProvider.tsx? So you can use the component as a client component, but still get a nice error message if you try to say use useQueryClient in a nested Server Component somewhere? I think for this PR it's probably fine to just do 'use client' at the top of those files and live with a bad worse error message for a while though, it's all pretty experimental anyway. 😄

@TkDodo

Copy link
Copy Markdown
Collaborator

I think this also means we might want to split any file that has both client components and hooks into two separate ones, like Hydrate.tsx and QueryClientProvider.tsx?

oh yeah, good idea. I think in v5 the Hydrate is no longer a problem because we have removed the hook already, but it makes sense for QueryClientProvider

@Ephem

Copy link
Copy Markdown
Collaborator

I took the liberty of removing the 'use client' from the hooks files again, but didn't split the files, I think we can do that later. I think isRestoring.tsx is another annoying candidate btw:

'use client'import*asReactfrom'react'constIsRestoringContext=React.createContext(false)exportconstuseIsRestoring=()=>React.useContext(IsRestoringContext)exportconstIsRestoringProvider=IsRestoringContext.Provider

Any such context/useContext pattern will need to be split into two files to get good error messages for the useContext part..

@EphemEphem changed the title perf(client components): added use client directive at the top of files having client componentsfeat(client components): add use client directive at the top of files having client componentsJan 24, 2023
@Ephem
Ephem merged commit f57c8dc into TanStack:mainJan 24, 2023
@girishsontakke
girishsontakke deleted the issue-4689 branch January 24, 2023 12:14
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants

@girishsontakke@TkDodo@codecov-commenter@Ephem
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

feat(client components): add use client directive at the top of files having client components - #4738

Merged
Ephem merged 9 commits into
TanStack:mainfrom
girishsontakke:issue-4689
Jan 24, 2023
Merged

feat(client components): add use client directive at the top of files having client components#4738
Ephem merged 9 commits into
TanStack:mainfrom
girishsontakke:issue-4689

Conversation

@girishsontakke

Copy link
Copy Markdown
Contributor

This PR is addressing the improvement suggested in #4689.

@codesandbox-ci

codesandbox-ciBot commented Jan 2, 2023

Copy link
Copy Markdown

This pull request is automatically built and testable in CodeSandbox.

To see build info of the built libraries, click here or the icon next to each commit SHA.

Latest deployment of this branch, based on commit a28c5a0:

SandboxSource
@tanstack/query-example-react-basic-typescriptConfiguration
@tanstack/query-example-solid-basic-typescriptConfiguration
@tanstack/query-example-svelte-basicConfiguration
@tanstack/query-example-vue-basicConfiguration

@TkDodoTkDodo left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Thanks. I think there are still a couple of places missing like:

  • useIsFetching
  • useIsMutating
  • the devtools
  • the react-query-persist package

@TkDodo

Copy link
Copy Markdown
Collaborator

not sure where all the conflicts are coming from. can you update with main once more please?

@girishsontakke

girishsontakke commented Jan 14, 2023

Copy link
Copy Markdown
ContributorAuthor

not sure where all the conflicts are coming from. can you update with main once more please?

Sure, I have removed the conflicts.

@codecov-commenter

codecov-commenter commented Jan 14, 2023

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 91.25%. Comparing base (eab6e2c) to head (a28c5a0).
⚠️ Report is 2966 commits behind head on main.

❗ There is a different number of reports uploaded between BASE (eab6e2c) and HEAD (a28c5a0). Click for more details.

HEAD has 2 uploads less than BASE
FlagBASE (eab6e2c)HEAD (a28c5a0)
31
Additional details and impacted files
@@ Coverage Diff @@## main #4738 +/- ##
==========================================
- Coverage 96.36% 91.25% -5.11% 
==========================================
Files 45 110 +65 Lines 2281 4116 +1835 Branches 640 1057 +417 ==========================================
+ Hits 2198 3756 +1558 - Misses 80 339 +259 - Partials 3 21 +18 

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@TkDodoTkDodo left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

there are more things that should be client components. Basically, everything that uses state, effects or context needs to be a client component. I haven't looked at the full list, but:

  • hydrate.tsx is definitely a client component
  • isRestoring.tsx` has react context

@Ephem

Copy link
Copy Markdown
Collaborator

Thanks for working on this!

I finally got around to do some testing, and I actually think we should not include 'use client' at the top of hooks-only files. First of all, it doesn't really have an effect because the components that use the hooks still needs to include the directive.

Second, having it in the hooks-only files actually hurts in a sense. If you forget to add 'use client' to a component that uses one of these hooks (will be a very common mistake in userland), the default is that you get a nice error message from React:

image

But if you have 'use client' in the hooks file, you instead get an unreadable build error (I guess because the file is still removed from the SC-bundle):

image

@TkDodo I think this also means we might want to split any file that has both client components and hooks into two separate ones, like Hydrate.tsx and QueryClientProvider.tsx? So you can use the component as a client component, but still get a nice error message if you try to say use useQueryClient in a nested Server Component somewhere? I think for this PR it's probably fine to just do 'use client' at the top of those files and live with a bad worse error message for a while though, it's all pretty experimental anyway. 😄

@TkDodo

Copy link
Copy Markdown
Collaborator

I think this also means we might want to split any file that has both client components and hooks into two separate ones, like Hydrate.tsx and QueryClientProvider.tsx?

oh yeah, good idea. I think in v5 the Hydrate is no longer a problem because we have removed the hook already, but it makes sense for QueryClientProvider

@Ephem

Copy link
Copy Markdown
Collaborator

I took the liberty of removing the 'use client' from the hooks files again, but didn't split the files, I think we can do that later. I think isRestoring.tsx is another annoying candidate btw:

'use client'import*asReactfrom'react'constIsRestoringContext=React.createContext(false)exportconstuseIsRestoring=()=>React.useContext(IsRestoringContext)exportconstIsRestoringProvider=IsRestoringContext.Provider

Any such context/useContext pattern will need to be split into two files to get good error messages for the useContext part..

@EphemEphem changed the title perf(client components): added use client directive at the top of files having client componentsfeat(client components): add use client directive at the top of files having client componentsJan 24, 2023
@Ephem
Ephem merged commit f57c8dc into TanStack:mainJan 24, 2023
@girishsontakke
girishsontakke deleted the issue-4689 branch January 24, 2023 12:14
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants

@girishsontakke@TkDodo@codecov-commenter@Ephem
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

feat(client components): add use client directive at the top of files having client components - #4738

Merged
Ephem merged 9 commits into
TanStack:mainfrom
girishsontakke:issue-4689
Jan 24, 2023
Merged

feat(client components): add use client directive at the top of files having client components#4738
Ephem merged 9 commits into
TanStack:mainfrom
girishsontakke:issue-4689

Conversation

@girishsontakke

Copy link
Copy Markdown
Contributor

This PR is addressing the improvement suggested in #4689.

@codesandbox-ci

codesandbox-ciBot commented Jan 2, 2023

Copy link
Copy Markdown

This pull request is automatically built and testable in CodeSandbox.

To see build info of the built libraries, click here or the icon next to each commit SHA.

Latest deployment of this branch, based on commit a28c5a0:

SandboxSource
@tanstack/query-example-react-basic-typescriptConfiguration
@tanstack/query-example-solid-basic-typescriptConfiguration
@tanstack/query-example-svelte-basicConfiguration
@tanstack/query-example-vue-basicConfiguration

@TkDodoTkDodo left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Thanks. I think there are still a couple of places missing like:

  • useIsFetching
  • useIsMutating
  • the devtools
  • the react-query-persist package

@TkDodo

Copy link
Copy Markdown
Collaborator

not sure where all the conflicts are coming from. can you update with main once more please?

@girishsontakke

girishsontakke commented Jan 14, 2023

Copy link
Copy Markdown
ContributorAuthor

not sure where all the conflicts are coming from. can you update with main once more please?

Sure, I have removed the conflicts.

@codecov-commenter

codecov-commenter commented Jan 14, 2023

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 91.25%. Comparing base (eab6e2c) to head (a28c5a0).
⚠️ Report is 2966 commits behind head on main.

❗ There is a different number of reports uploaded between BASE (eab6e2c) and HEAD (a28c5a0). Click for more details.

HEAD has 2 uploads less than BASE
FlagBASE (eab6e2c)HEAD (a28c5a0)
31
Additional details and impacted files
@@ Coverage Diff @@## main #4738 +/- ##
==========================================
- Coverage 96.36% 91.25% -5.11% 
==========================================
Files 45 110 +65 Lines 2281 4116 +1835 Branches 640 1057 +417 ==========================================
+ Hits 2198 3756 +1558 - Misses 80 339 +259 - Partials 3 21 +18 

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@TkDodoTkDodo left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

there are more things that should be client components. Basically, everything that uses state, effects or context needs to be a client component. I haven't looked at the full list, but:

  • hydrate.tsx is definitely a client component
  • isRestoring.tsx` has react context

@Ephem

Copy link
Copy Markdown
Collaborator

Thanks for working on this!

I finally got around to do some testing, and I actually think we should not include 'use client' at the top of hooks-only files. First of all, it doesn't really have an effect because the components that use the hooks still needs to include the directive.

Second, having it in the hooks-only files actually hurts in a sense. If you forget to add 'use client' to a component that uses one of these hooks (will be a very common mistake in userland), the default is that you get a nice error message from React:

image

But if you have 'use client' in the hooks file, you instead get an unreadable build error (I guess because the file is still removed from the SC-bundle):

image

@TkDodo I think this also means we might want to split any file that has both client components and hooks into two separate ones, like Hydrate.tsx and QueryClientProvider.tsx? So you can use the component as a client component, but still get a nice error message if you try to say use useQueryClient in a nested Server Component somewhere? I think for this PR it's probably fine to just do 'use client' at the top of those files and live with a bad worse error message for a while though, it's all pretty experimental anyway. 😄

@TkDodo

Copy link
Copy Markdown
Collaborator

I think this also means we might want to split any file that has both client components and hooks into two separate ones, like Hydrate.tsx and QueryClientProvider.tsx?

oh yeah, good idea. I think in v5 the Hydrate is no longer a problem because we have removed the hook already, but it makes sense for QueryClientProvider

@Ephem

Copy link
Copy Markdown
Collaborator

I took the liberty of removing the 'use client' from the hooks files again, but didn't split the files, I think we can do that later. I think isRestoring.tsx is another annoying candidate btw:

'use client'import*asReactfrom'react'constIsRestoringContext=React.createContext(false)exportconstuseIsRestoring=()=>React.useContext(IsRestoringContext)exportconstIsRestoringProvider=IsRestoringContext.Provider

Any such context/useContext pattern will need to be split into two files to get good error messages for the useContext part..

@EphemEphem changed the title perf(client components): added use client directive at the top of files having client componentsfeat(client components): add use client directive at the top of files having client componentsJan 24, 2023
@Ephem
Ephem merged commit f57c8dc into TanStack:mainJan 24, 2023
@girishsontakke
girishsontakke deleted the issue-4689 branch January 24, 2023 12:14
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants

@girishsontakke@TkDodo@codecov-commenter@Ephem
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

feat(client components): add use client directive at the top of files having client components - #4738

Merged
Ephem merged 9 commits into
TanStack:mainfrom
girishsontakke:issue-4689
Jan 24, 2023
Merged

feat(client components): add use client directive at the top of files having client components#4738
Ephem merged 9 commits into
TanStack:mainfrom
girishsontakke:issue-4689

Conversation

@girishsontakke

Copy link
Copy Markdown
Contributor

This PR is addressing the improvement suggested in #4689.

@codesandbox-ci

codesandbox-ciBot commented Jan 2, 2023

Copy link
Copy Markdown

This pull request is automatically built and testable in CodeSandbox.

To see build info of the built libraries, click here or the icon next to each commit SHA.

Latest deployment of this branch, based on commit a28c5a0:

SandboxSource
@tanstack/query-example-react-basic-typescriptConfiguration
@tanstack/query-example-solid-basic-typescriptConfiguration
@tanstack/query-example-svelte-basicConfiguration
@tanstack/query-example-vue-basicConfiguration

@TkDodoTkDodo left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Thanks. I think there are still a couple of places missing like:

  • useIsFetching
  • useIsMutating
  • the devtools
  • the react-query-persist package

@TkDodo

Copy link
Copy Markdown
Collaborator

not sure where all the conflicts are coming from. can you update with main once more please?

@girishsontakke

girishsontakke commented Jan 14, 2023

Copy link
Copy Markdown
ContributorAuthor

not sure where all the conflicts are coming from. can you update with main once more please?

Sure, I have removed the conflicts.

@codecov-commenter

codecov-commenter commented Jan 14, 2023

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 91.25%. Comparing base (eab6e2c) to head (a28c5a0).
⚠️ Report is 2966 commits behind head on main.

❗ There is a different number of reports uploaded between BASE (eab6e2c) and HEAD (a28c5a0). Click for more details.

HEAD has 2 uploads less than BASE
FlagBASE (eab6e2c)HEAD (a28c5a0)
31
Additional details and impacted files
@@ Coverage Diff @@## main #4738 +/- ##
==========================================
- Coverage 96.36% 91.25% -5.11% 
==========================================
Files 45 110 +65 Lines 2281 4116 +1835 Branches 640 1057 +417 ==========================================
+ Hits 2198 3756 +1558 - Misses 80 339 +259 - Partials 3 21 +18 

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@TkDodoTkDodo left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

there are more things that should be client components. Basically, everything that uses state, effects or context needs to be a client component. I haven't looked at the full list, but:

  • hydrate.tsx is definitely a client component
  • isRestoring.tsx` has react context

@Ephem

Copy link
Copy Markdown
Collaborator

Thanks for working on this!

I finally got around to do some testing, and I actually think we should not include 'use client' at the top of hooks-only files. First of all, it doesn't really have an effect because the components that use the hooks still needs to include the directive.

Second, having it in the hooks-only files actually hurts in a sense. If you forget to add 'use client' to a component that uses one of these hooks (will be a very common mistake in userland), the default is that you get a nice error message from React:

image

But if you have 'use client' in the hooks file, you instead get an unreadable build error (I guess because the file is still removed from the SC-bundle):

image

@TkDodo I think this also means we might want to split any file that has both client components and hooks into two separate ones, like Hydrate.tsx and QueryClientProvider.tsx? So you can use the component as a client component, but still get a nice error message if you try to say use useQueryClient in a nested Server Component somewhere? I think for this PR it's probably fine to just do 'use client' at the top of those files and live with a bad worse error message for a while though, it's all pretty experimental anyway. 😄

@TkDodo

Copy link
Copy Markdown
Collaborator

I think this also means we might want to split any file that has both client components and hooks into two separate ones, like Hydrate.tsx and QueryClientProvider.tsx?

oh yeah, good idea. I think in v5 the Hydrate is no longer a problem because we have removed the hook already, but it makes sense for QueryClientProvider

@Ephem

Copy link
Copy Markdown
Collaborator

I took the liberty of removing the 'use client' from the hooks files again, but didn't split the files, I think we can do that later. I think isRestoring.tsx is another annoying candidate btw:

'use client'import*asReactfrom'react'constIsRestoringContext=React.createContext(false)exportconstuseIsRestoring=()=>React.useContext(IsRestoringContext)exportconstIsRestoringProvider=IsRestoringContext.Provider

Any such context/useContext pattern will need to be split into two files to get good error messages for the useContext part..

@EphemEphem changed the title perf(client components): added use client directive at the top of files having client componentsfeat(client components): add use client directive at the top of files having client componentsJan 24, 2023
@Ephem
Ephem merged commit f57c8dc into TanStack:mainJan 24, 2023
@girishsontakke
girishsontakke deleted the issue-4689 branch January 24, 2023 12:14
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants

@girishsontakke@TkDodo@codecov-commenter@Ephem