jss icon indicating copy to clipboard operation
jss copied to clipboard

Error with multiple same component child

Open Yomyer opened this issue 5 years ago • 6 comments

Expected behavior: It should not display such a warning

Describe the bug: I get the warning: Warning: [JSS] Rule is not linked. Missing sheet option "link: true". when I duplicate in a component the same child component when it has a dynamic value. I am using Next SSR and have already reported the problem but I don't know where the problem is coming from.

https://github.com/vercel/next.js/issues/23872

If it only appears once it does not show the warning

Thanks ;)

Reproduction: Install the example with-react-jss-app

npx create-next-app --example with-react-jss with-react-jss-app Then modify the pages/index.js to

import { createUseStyles } from 'react-jss'
const useStyes = createUseStyles({
  header: {
    color: props => props.color
  }
})

const Bar = () => {
  const classes = useStyes({ color: 'green' });

  return (
    <>
      <h2 className={classes.header}>dasdasda</h2>
    </>
  )
}

function Index() {
  return (
    <div>
      <h1>
        Example on how to use react-jss with Next.js
      </h1>
      <Bar></Bar>
      <Bar></Bar>
    </div>
  )
}

export default Index

Run in dev mode

npm run dev o yarn dev And it will show the warning:

Warning: [JSS] Rule is not linked. Missing sheet option "link: true".

Versions (please complete the following information):

  • jss: 10.6.0
  • Browser [e.g. chrome, safari]: All browsers, Occurs on the SSR server
  • OS [e.g. Windows, macOS]: macOs

Yomyer avatar Apr 10 '21 16:04 Yomyer

The logic which shows this error must be thinking code is running on the client. Something is wrong with the detection mechanism. Feel free to debug.

kof avatar Apr 26 '21 09:04 kof

@kof Can you point me to the place where detection mechanism is located?

My current observation is that this happens exclusively with Next.js (I've tested the same components with Gatsby and custom server, all of them do not show the warning)

I guess the dumbest solution will be to replace this with:

if (typeof window !== 'undefined' && sheet && sheet.attached) {
  warning(false, '[JSS] Rule is not linked. Missing sheet option "link: true".')
}

rtivital avatar Jun 30 '21 18:06 rtivital

Not sure, from a quick look it should be broken for all platforms, because they will be getting to this warning because there is no renderable on the server and the still has sheet.attached===true and you get there most likely from react-jss updateDynamicRules() then jss sheet.updateOne().

I don't see from reading the jss code why this would only happen on next and not on gatsby. Only if gatsby has dom api exposed serverside too.

kof avatar Jul 02 '21 00:07 kof

I am thinking that sheet.attached there assumed it can only be true when on the client but ages ago we changed that so that sheet can be attached serverside but do nothing in dom renderer.

kof avatar Jul 02 '21 00:07 kof

In theory the missing piece is that .renderer should be null serverside in style rule, so react-jss should be passing Renderer: null to jss.createStyleSheet({Renderer: null}) when serverside and in addition to that we should if (this.renderer === null) return this here

We also need a test in react-jss for this and ideally we need to understand how this is not happening for everybody, but only in next, it seems to me it should be broken for everybody when styles with function values are used in react-jss.

kof avatar Jul 02 '21 00:07 kof

@kof I've managed to replicate this issue with regular ssr server (not Next), here what I did:

  getDataFromTree(_App).then(() => {
    const initialState = client.extract();

    const registry = new SheetsRegistry();

    const c = renderToString(
      <JssProvider registry={registry} generateId={createGenerateId()}>
        {_App}
      </JssProvider>
    );

    const html = renderToStaticMarkup(
      <Html
        helmetContext={helmetContext}
        scripts={[res.locals.assetPath('bundle.js'), res.locals.assetPath('vendor.js')]}
        styles={registry.toString()}
        apolloState={initialState}
      >
        {c}
      </Html>
    );

    res.status(200);
    res.send(`<!doctype html>\n${html}`);
  });

And then in console

Снимок экрана 2021-08-17 в 12 53 05

rtivital avatar Aug 17 '21 09:08 rtivital