React Styled Components — Hooks, Refs, and Security
Tags: react, webdev, programming, javascript
Published: 2021-01-23 19:48:49

**Check out my books on Amazon at https://www.amazon.com/John-Au-Yeung/e/B08FT5NT62**

**Subscribe to my email list now at http://jauyeung.net/subscribe/**

React is the most used front end library for building modern, interactive front end web apps. It can also be used to build mobile apps.

In this article, we’ll look at how to access themes with hooks, referencing DOM elements with refs, and dealing with security.

### Accessing Themes Using the useContext React Hook

We can use the `useContext` React hook with the `ThemeContext` to access theme properties with hooks.

For instance, we can do that as follows:

```
import React, { useContext } from "react";
import { ThemeProvider, ThemeContext } from "styled-components";

const baseTheme = {
  color: "green",
  backgroundColor: "white"
};

const Foo = ({ children }) => {
  const themeContext = useContext(ThemeContext);
  return <div style={themeContext}>{children}</div>;
};

export default function App() {
  return (
    <div>
      <ThemeProvider theme={baseTheme}>
        <Foo>foo</Foo>
      </ThemeProvider>
    </div>
  );
}
```

In the code above, we used `useContext` with `ThemeContext` passed in to access the theme. `themeContext` has the exact same properties and values as `baseTheme` . Therefore, we can pass `themeContext` straight in as the value of the `style` prop.

In `App` , we wrapped `ThemeProvider` with `theme` set to `baseTheme` so that we can access the theme properties that are in `baseTheme` .

Therefore, we’ll see that ‘foo’ is displayed in green.

### The theme Prop

We can pass themes down to child components with the `theme` prop. This works with components created with `styled-components`. For instance, we can do that as follows:

```
import React from "react";
import styled, { ThemeProvider } from "styled-components";

const Button = styled.button`
  font-size: 12px;
  margin: 5px;
  padding: 6px;
  border-radius: 3px;

color: ${props => props.theme.main};
  border: 2px solid ${props => props.theme.main};
`;

const theme = {
  main: "green"
};

export default function App() {
  return (
    <div>
      <ThemeProvider theme={theme}>
        <Button theme={{ main: "blue" }}>Foo</Button>
        <ThemeProvider theme={theme}>
          <div>
            <Button>Baz</Button>
            <Button theme={{ main: "red" }}>Bar</Button>
          </div>
        </ThemeProvider>
      </ThemeProvider>
    </div>
  );
}
```

In the code above, we created a styled button with various styles. The colors are passed in from the theme and we access it with the `prop.theme.main` property.

Then in `App` , we use the `theme` prop to pass in different colors for some of the buttons. The Foo button is blue and the Bar button is red.

They will override the original color value that’s specified in `theme` , which is `green` .

Therefore, we’ll see buttons that have red, green or blue text border and color. Foo is blue, Baz is green, and Bar is red,

### Refs

We can pass in refs to a styled component to access the DOM properties and methods for the given styled component.

For instance, we can do that as follows:

```
import React from "react";
import styled from "styled-components";

const Input = styled.input`
  padding: 0.5em;
  margin: 0.5em;
  background: greenyellow;
  border: none;
  border-radius: 3px;
`;

export default function App() {
  const inputRef = React.useRef();
  React.useEffect(() => {
    inputRef.current.focus();
  }, []);
  return (
    <div>
      <Input ref={inputRef} />
    </div>
  );
}
```

In the code above, we created a styled input called `Input`. Then we passed in a ref created with the `useRef` hook to `Input` .

Then in the `useEffect` callback, we call `inputRef.current.focus();` to focus the element. The empty array in the 2nd argument of `useEffect` indicates that we load the callback when `App` first loads.

Therefore, when we first load the page, the `Input` will be focused on.

![](https://cdn-images-1.medium.com/max/800/0*UMAovnNgO2Dr9HnR)Photo by [Icons8 Team](https://unsplash.com/@icons8?utm_source=medium&utm_medium=referral) on [Unsplash](https://unsplash.com?utm_source=medium&utm_medium=referral)

### Security

Security is a concern when creating styled-components with `styled-components` because all the text is interpolated in our styled component if we pass them in via props, themes, or anywhere else.

Therefore, we should sanitize any input that’s passed in. For instance, the following would be bad:

```
import React from "react";
import styled from "styled-components";

const userInput = "/steal-money";

const ArbitraryComponent = styled.div`
  background: url(${userInput});
`;

export default function App() {
  return (
    <div>
      <ArbitraryComponent />
    </div>
  );
}
```

since we load the URL in our code, which isn’t good. Therefore, we should add some checks to avoid this from happening.

### Conclusion

We can access themes with the `useContext` hook. Also, we can pass in the `theme` prop to pass in theme properties to override the values in the base theme.

`styled-components` will forward refs to our HTML element so that we can get the HTML element that’s in the styled component created with the package via the refs.

Finally, we should be careful when we’re interpolating strings in our styling code to avoid arbitrary code execution attacks.