Skip to content
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

SSR tabs are not reused on client #384

Closed
mskec opened this issue Dec 20, 2016 · 3 comments
Closed

SSR tabs are not reused on client #384

mskec opened this issue Dec 20, 2016 · 3 comments

Comments

@mskec
Copy link

mskec commented Dec 20, 2016

Bug report

  • Package version(s): 1.4.0
  • Browser and OS versions: Chrome 54.0.2840.98, OSX 10.11.6

Steps to reproduce

I don't have clean repo to provide with example, but sample usage example for tabs with SSR enabled project will be enough to reproduce the problem.

Actual behavior

I am getting this warning when rendering Sample Usage example.

Warning: React attempted to reuse markup in a container but the checksum was invalid. This generally means that you are using server rendering and the markup generated on the server was not what the client was expecting. React injected new markup to compensate which works but you have lost many of the benefits of server rendering. Instead, figure out why the markup being generated is different on the client or server:
 (client) trols="pt-tab-panel-0" aria-disabled="fa
 (server) trols="pt-tab-panel-20" aria-disabled="f

Every time I reload page, server rendered tabs get ID that is increasing.
I think the problem is in the way IDs are generated here. Module scoped variable is used to count tabs which gets initialized on 1st import and keeps increasing on each server render.

Expected behavior

Expected behavior would be that tabs are rendered in isolation and markup is reused on client.

@mskec mskec changed the title SSR tabs SSR tabs are not reused on client Dec 20, 2016
@adidahiya
Copy link
Contributor

Fair point; the code you pointed out is a lazy implementation of tab IDs. We should probably use something like the uuid module.

@giladgray
Copy link
Contributor

giladgray commented Feb 23, 2017

Wow this is a nasty problem that has not been solved in the React ecosystem. See facebook/react#4000 and facebook/react#5867 for more context.

I think required ids are going to be our best friends here, although it pushes the uniqueness problem to the consumer. In my new Tabs API, each Tab will require a (locally) unique id and we'll use activeTabId instead of the current index approach. If we simply require a "unique" id on the Tabs parent then we should have enough information to generate unique IDs that are consistent on both server and client.

Example:

<Tabs id="tabs1" activeTabId="pear">
    <Tab id="apple" text="Apple" />    // #__tab-tabs1-apple
    <Tab id="banana" text="Banana" />  // #__tab-tabs1-banana
    <Tab id="pear" text="Pear" />      // #__tab-tabs1-pear
</Tabs>
<Tabs id="tabs2" activeTabId="apple">
    <Tab id="apple" text="Apple" />    // #__tab-tabs2-apple
    <Tab id="banana" text="Banana" />  // #__tab-tabs2-banana
    <Tab id="pear" text="Pear" />      // #__tab-tabs2-pear
</Tabs>

I hypothesize that folks won't use many Tabs in a single application so managing this should not be fairly painless for consumers.

@adidahiya
Copy link
Contributor

@giladgray I agree with your assessment. Users are probably already supplying unique key prop values as well

giladgray pushed a commit that referenced this issue Feb 23, 2017
needs unique IDs in DOM, so `Tabs` and `Tab` both require `id` prop in order to generate unique-enough ID. hand-coded IDs like this should also solve #384 (SSR Tabs).
giladgray added a commit that referenced this issue Mar 3, 2017
* new 2-component Tabs API
`Tabs` wrapper coordinates the whole thing. `Tab` children must have `title`. Can supply other children to appear in tab title row.
* tests! defaultSelectedTabIndex!
* awesome keyboard support: up/left, down/right, space/enter
* animated indicator support somehow doesn't need any timeouts!
happily supports the edge case that we tested for previously (title changing with selection). i wasn't able to test it, though, as the indicator assertion requires the root enzyme wrapper in order to access state, so i instead updated the example.
* refactor to select by tab id instead of index
requires that every `<Tab>` must have an `id` (does not validate uniqueness) (all for you, @ericanderson)
* render all tab panels by default. `renderActiveTabPanelOnly` prop reverts to previous behavior
* aria-* props support
needs unique IDs in DOM, so `Tabs` and `Tab` both require `id` prop in order to generate unique-enough ID. hand-coded IDs like this should also solve #384 (SSR Tabs).
* controlled mode through `selectedTabId` prop
* add `Tabs2.Expander` for right-aligning children
* add `panel` prop to `Tab2`, title can be prop or children
* Fix navbar position for all examples
@adidahiya adidahiya added this to the 1.11.0 milestone Mar 3, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants