使用样式化组件样式化 react-router-dom Link 在传递道具时收到警告

Styling react-router-dom Link using styled-components getting warning when passing props

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

const LS = {};

LS.NavFixedItem_LINK = styled(Link)`

  display: flex;
  justify-content: ${props => props.tempLeftProp ? 'flex-start' : 'center'};
  align-items: center;
`;

function NavFixedItem(props) {
  return(
    <LS.NavFixedItem_LINK to={props.link} tempLeftProp={props.toLeft}>
      {props.name}
    </LS.NavFixedItem_LINK>
  );
}

我遇到错误:

Warning: React does not recognize the tempLeftProp prop on a DOM element. If you intentionally want it to appear in the DOM as a custom attribute, spell it as lowercase templeftprop instead. If you accidentally passed it from a parent component, remove it from the DOM element.

我一直将道具传递给我的样式组件。我不知道问题是否在于我正在设计组件 Link 而不是常规 HTML 元素的样式。

问题

为什么会出现此错误?忽略它是否安全?

PS:正在按预期应用样式。

在内部,React Router 的 Link 将其所有属性传递给 <a> DOM 元素。除了 Link 使用的那些,例如 to。所以样式之所以有效,是因为 props 由 Styled Components 解释,但随后相同的 prop 再次传递到内部 <a>,这会触发(无害的)错误消息。

您可以尝试使用嵌套样式的包装器,如下所示:

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>
  );
}

另一件事你可以尝试 "to" prop on a react Link 标签可以接受两个不同的值,一个字符串或一个对象。

  1. 如果是字符串,则表示link的绝对路径,例如/users/123(不支持相对路径)。
  2. 如果是一个对象,它可以有四个键:

    • pathname: 代表路径的字符串link to.
    • query: key:value 对的对象被字符串化。
    • hash:要放入 URL 的散列,例如#a-hash.
    • state: state 要保存到位置。

你上面的代码可以表示为:

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>
  );
}

使用瞬态道具

在 5.1.0 版本中,您可以使用 transient props。这样你就不需要额外的包装器,即减少了不必要的代码:

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.

新答案应该是:

样式组件:

LS.NavFixedItem_LINK = styled(Link)`
  display: flex;
  justify-content: ${props => props.$tempLeftProp ? 'flex-start' : 'center'}; // '$' added
  align-items: center;
`;

父组件:

function NavFixedItem(props) {
  return(
    <LS.NavFixedItem_LINK 
      to={props.link} 
      $tempLeftProp={props.toLeft} // '$' signals the transient prop
    >
      {props.name}
    </LS.NavFixedItem_LINK>
  );
}