Styling react-router-dom Link using styled-components getting warning when passing props
UPDATE 2020-04-07: Use transient props
With the release 5.1.0 you can use transient props. This way you do not need an extra wrapper i.e. unnecessary code is reduced:
Transient props are a new pattern to pass props that are explicitly consumed only by styled components and are not meant to be passed down to deeper component layers. Here's how you use them:
const Comp = styled.div`
color: ${props => props.$fg || 'black'};
`;
render(<Comp $fg="red">I'm red!</Comp>);
Note the dollar sign ($) prefix on the prop; this marks it as transient and styled-components knows not to add it to the rendered DOM element or pass it further down the component hierarchy.
The new answer should be:
styled component:
LS.NavFixedItem_LINK = styled(Link)`
display: flex;
justify-content: ${props => props.$tempLeftProp ? 'flex-start' : 'center'}; // '$' added
align-items: center;
`;
parent component:
function NavFixedItem(props) {
return(
<LS.NavFixedItem_LINK
to={props.link}
$tempLeftProp={props.toLeft} // '$' signals the transient prop
>
{props.name}
</LS.NavFixedItem_LINK>
);
}
Internally, React Router's Link
passes all the its props to an <a>
DOM element. Except the ones used by Link
, like to
. So the styles work because the props are interpreted by Styled Components, but then the same prop is passed again to the inner <a>
, which triggers the (harmless) error message.
You could try having a wrapper with nested styles, like this:
LS.NavFixedItem_LINK = styled.div`
a {
display: flex;
justify-content: ${props => props.tempLeftProp ? 'flex-start' : 'center'};
align-items: center;
}
`;
function NavFixedItem(props) {
return(
<LS.NavFixedItem_LINK tempLeftProp={props.toLeft}>
<Link to={props.link}>
{props.name}
</Link>
</LS.NavFixedItem_LINK>
);
}
another thing you could try the "to" prop on a react Link tag can take two different values a string or an object.
- If it's a string, it represents the absolute path to link to, e.g.
/users/123
(relative paths are not supported). If it's an object, it can have four keys:
- pathname: A string representing the path to link to.
- query: An object of
key:value
pairs to be stringified. - hash: A hash to put in the URL, e.g.
#a-hash
. - state: State to persist to the location.
your above code can be represented as:
import styled from 'styled-components';
import {Link} from 'react-router-dom';
const LS = {};
LS.NavFixedItem_LINK = styled(Link)`
display: flex;
justify-content: ${props => props.to.state.tempLeftProp ? 'flex-start' : 'center'};
align-items: center;
`;
function NavFixedItem(props) {
return(
<LS.NavFixedItem_LINK to={{ pathname: props.link, state: {tempLeftProp: props.toLeft} }}>
{props.name}
</LS.NavFixedItem_LINK>
);
}