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.
Photo by Icons8 Team on Unsplash
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.