Next.js: Incrementing element Id with react and next.js

Created on 25 Feb 2019  路  4Comments  路  Source: vercel/next.js

Bug report

Describe the bug

I need to have a unique Id for every rendered element, so I count them. But I have SSR with Next.js. When the page initializes on the server then idCounter is incremented few times because of server rendering.

Then normal browser tries to render this component starting idCounter from 0 and replacing server-side rendered id (e.g. "TestComponent-5" to "TestComponent-0"). And I end up with error in console:

"Warning: Prop id did not match. Server: "TestComponent-5" Client: "TestComponent-0" "

Bug is telling me nothing. Page got destroyed.

To Reproduce

Create such component and render it with react and next.js:

let idCounter = 0;

export default class TestComponent extends Component {
  constructor(props) {
    super(props);

    this.uniqueId = `TestComponent-${idCounter++}`;
  }

  render() {
     return (<div id={this.uniqueId> Some content </div>);
  }
}

Expected behavior

'id' property should be overridden by browser id value. No error should be displayed.

System information

  • OS: Windows 10
  • Browser (if applies) The newest Chrome
  • Version of Next.js: "7.0.2"

Most helpful comment

I have some third party library which uses id to add some special effect to the given element.
I can define id manually. But there can be few of those elements on the site. In different component locations. I wrote a wrapper for usage of that component to be always sure that id would be always different. (If some other person will put the same id for the component somewhere else we would have a problem). But I'm forced to work on ids because of that third party library (I know refs are better, but I can't use them). How can I create unique identifier which will be different for every component instance and the same for server and browser?

All 4 comments

It's generally a bad idea to depend on module state while rendering. As you've experienced yourself state is not transferred to the client side (and it shouldn't be transferred like that).

It can also cause multiple requests to get eachother's values because the module state is not user-specific.

@timneutkens maybe would you use some arguments instead saying "It's generally a bad idea".
I understand it is not transferred to the client side, but why it can't be rerendered on the frontend site with newly created ids by the browser? Because next.j is blocking it with that error. And how we should handle such cases?

So basically you're adding a side-effect to rendering, which means that render() is not deterministic, this will for example break with concurrent React. What are you trying to solve exactly? Why can't the ids be deterministic?

I have some third party library which uses id to add some special effect to the given element.
I can define id manually. But there can be few of those elements on the site. In different component locations. I wrote a wrapper for usage of that component to be always sure that id would be always different. (If some other person will put the same id for the component somewhere else we would have a problem). But I'm forced to work on ids because of that third party library (I know refs are better, but I can't use them). How can I create unique identifier which will be different for every component instance and the same for server and browser?

Was this page helpful?
0 / 5 - 0 ratings