validateDOMNesting warning React

Viewed 25399

I have a React component that is clickable as a whole, but also contains buttons inside.

So something like

<Link to={'/path1'}>
  ...
  <Link to={'path2'} />
  ...
</Link> 

This is the behaviour I want, but I get this warning:

Warning: validateDOMNesting(...): <a> cannot appear as a descendant of <a>. See SearchResult > Link > a > ... > Link > a.

How seriously should I take this and what would be the workaround?

2 Answers

Nesting anchor tags (which is what <Link /> transpiles to) is forbidden in HTML. Even if you get the desired result, it is only because your browser is clever and has its own work-arounds. However, that behavior cannot be guaranteed across all browsers and platforms.

How seriously should I take this?

As per the above, I'd say quite seriously.

What would be the workaround?

The following isn't a workaround, but what I consider to be the "proper" implementation.

I'd programatically implement the navigation for the wrapping element and use the <Link /> for the buttons. So something like:

navigate = () => {
  //push "path1" to history
}

render() {
  return(
    <div onClick={this.navigate}>
      <Link to="path2">Some button</Link>
      <Link to="path3">Some button</Link>
    </div>
  );
}

For more info about programatically navigating in React Router see one of the links below:

  • For React Router v1-v3: Link
  • For React Router v4: Link

I think the best approach is something similar to what Chris said but without the need to make the navigation programmatically. Keep the default behaviour of the links and use CSS to make them appear nested. As far as the browser is concerned, the links will be siblings and not parent/child.

So basically:

  • set the surrounding div's position to relative.
  • no explicit position to the 'parent' link, and let it use the whole width/height
  • set the 'child' link's position to absolute, which will remove it from the normal flow and will allow you to put it anywhere inside the div. Events shouldn't conflict because the links are not nested.

EDIT: I know this answer comes years later, but I expect many people to come across this problem since it is a common UI pattern.

Related