How to style your React-Router links using styled-components

ridhikgovind

Ridhik Govind

Posted on February 28, 2021

How to style your React-Router links using styled-components

So you've just started using React-Router for easily routing the pages in your React-web app and if you're also using Styled-components, then kudos - this article is for you. In this article I will explain how to easily style your React-Router Links by going through 3 main methods of styling.

Goals - To code out efficient and cleaner code that are reusable that can help us when we are making our application bigger.

Note: It is assumed that you already know how to work with React Router and styled-components at a basic level

METHOD 1: Styling links using inline style attribute.

//Nav.js  

import { Link } from "react-router-dom";
import styled from "styled-components";

const NavUnlisted = styled.ul`
  text-decoration: none;
`;

const linkStyle = {
  margin: "1rem",
  textDecoration: "none",
  color: 'blue'
};

function Nav() {
  return (
    <NavUnlisted>
      <Link to="/" style={linkStyle}>
        Home
      </Link>
      <Link to="/about" style={linkStyle}>
        About
      </Link>
    </NavUnlisted>
  );
}

export default Nav;

Enter fullscreen mode Exit fullscreen mode

gif

Explanation : So you have the following code with you. It contains an 'unordered nav list' component named NavUnlisted. But let's just keep our main focus on the Link component shall we. Now the thing is you cannot directly style the Link using styled components this way. Why ? Because under the hood, Link is just an anchor tag or <a> tag that we are importing from the styled-components. So we can't create a constant variable with this Link.

const Link = styled.a``;  //error - **Link** already has been declared
Enter fullscreen mode Exit fullscreen mode

Solution : Use inline style attribute. These basically are similar to how we use inline styles in HTML.So we create a style attribute with the styles inside it in an object form.

Conclusion : This is not so great way as it will become difficult to code out and track individual styles as the app scales - Also, it does not meet the standards of our Goals stated at the beginning of the article.

Here is a Codesandbox link if you are interesting in taking a quick glance at the code for METHOD-1 and if you wish you can follow along too.

METHOD 2: Styling links using 'styled.componentName' format.

If you are familiar with styled components, you should know that styled is like the very basic thing you import from styled-components.styled together with 'tagNames' (e.g div or li or h1 etc) or a valid component name can be used to apply styles to a component.

The reason why we can use the latter one i.e component name, is because we have imported a component here that is Link, now we can pass this Link like this:

const StyledLink  = styled(Link)`
     //some CSS styles here
`;
Enter fullscreen mode Exit fullscreen mode

Explanation : I know this one's a little tricky but here it goes. So basically what we are doing here is, we are creating a new component and telling it, "Hey I am a new component and I want to be like Mr.Link but in a stylish manner, so I am going to take all of the Mr.Link characteristics and add a little bit a style of my own". So in the end the code looks something like this:

const StyledLink = styled(Link)`
  color: Blue;
  text-decoration: none;
  margin: 1rem;
  position: relative;
`;

function Nav() {
  return (
    <NavUnlisted>
      <StyledLink to="/">Home</StyledLink>
      <StyledLink to="/about">About</StyledLink>
    </NavUnlisted>
  );
}
Enter fullscreen mode Exit fullscreen mode

Solution : Now you can style your Link directly by creating another component instance i.e StyledLink, and then applying style to it.

Conclusion : This is a cleaner way than METHOD-1 because unlike in the earlier method, here we are actually writing CSS. What I meant by is that - in METHOD-1,we had to write textDecoration instead of text-decoration. Are you just noticing this now ? Greatttt !

METHOD-3: Styling React-Router links using 'NavLinks' and 'activeClassNames'.

Well well well, this was the moment where I found something really interesting that led me to write this article. React-Router has a module called NavLinks that we can use as a component. What's so special about it you may ask ? Well, it was built specifically for styling links you use with React-Router. NAVLINK is provided by REACT-ROUTER and NOT by STYLED-COMPONENTS. Well, that a whole lot of Well's in one paragraph. Anyway, let's jump into the code but beware there are some major changes here:

import { NavLink } from "react-router-dom";  

const NavUnlisted = styled.ul`

  display: flex;

  a {
    text-decoration: none;
  }

  li {
    color: red;
    margin: 0 0.8rem;
    font-size: 1.3rem;
    position: relative;
    list-style: none;
  }

  .current {
    li {
      border-bottom: 2px solid black;
    }
  }
`;


function Nav() {
  return (
    <NavUnlisted>
      <NavLink to="/" activeClassName="current" exact>
        <li>Home</li>
      </NavLink>
      <NavLink to="/about" activeClassName="current" exact>
        <li>About</li>
      </NavLink>
    </NavUnlisted>
  );
}

Enter fullscreen mode Exit fullscreen mode

Explanation : So basically, NavLink is a special style of Link that we can add styles to it when it matches a certain path in the URL.So if I am currently in '/' i.e Home, I can apply a style border-bottom to the 'Home' link and if I am in '/about' path then apply style to 'About' link . It would look something like this:

gif

  • activeClassName is an attribute that we can use to create a class that we can later apply style to it. In our case, we have used the .current and li tag to make a border-bottom to the corresponding link whenenver the path of the URL changes.

  • exact keyword is used so as to specifically target the currently selected URL. So if the path is '/' then styling will ONLY be applied to the Home page. try removing the exact and see the effect for yourself

Solution : Using NavLink, we can save time by not writing any JavaScript for triggering the current selection and applying corresponding styling. Instead we can simply use the NavLink provided by the React-Router.

Conclusion : This method is effective when you want to apply certain specific styling e.g when the link is currently selected and so on.

METHOD - 4: Writing a much cleaner code for METHOD - 3 [BONUS PART]

const NavUnlisted = styled.ul`
  display: flex;
  a {
    text-decoration: none;
  }
  li {
    color: red;
    margin: 0 0.8rem;
    font-size: 1.3rem;
    position: relative;
    list-style: none;
  }

  .current {
    li {
      border-bottom: 2px solid black;
    }
  }
`;


const links = [
  {name: "Home",path:"/"},
  {name: "About",path:"/about"},
];

function Nav() {
  return (
    <NavUnlisted>
      {links.map((link,index) => (
        <NavLink key={index} to={link.path} exact activeClassName="current">
          <li>{link.name}</li>
        </NavLink>
      ))}
    </NavUnlisted>
  );
}

Enter fullscreen mode Exit fullscreen mode

Explanation: What we have done here is simple but it can save us a loads of time in the future if we want add or change links easily. Just create a new array with all the objects you need and just 'map' over them. That's pretty much it.

End

So I hope you have learned something new. If you happen to notice any errors or mistakes in this article please feel free to point it out. Wait... You have a much better way to do the above methods ?? Let me know in the comments below 😃

I know I know !

References:

Find the entire code for all the methods in this Codesandbox. Don't forget to uncomment the code for each method 😉

This is for the Twitter peeps - find me @fluffyRidz

💖 💪 🙅 🚩
ridhikgovind
Ridhik Govind

Posted on February 28, 2021

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related