React 包装器:React 无法识别 DOM 元素上的 `staticContext` 道具

Posted

技术标签:

【中文标题】React 包装器:React 无法识别 DOM 元素上的 `staticContext` 道具【英文标题】:React wrapper: React does not recognize the `staticContext` prop on a DOM element 【发布时间】:2020-09-02 21:39:32 【问题描述】:

我正在尝试围绕 react-router-dom NavLink 组件创建一个包装器组件。

我希望我的自定义组件接受所有 NavLinks 道具,并将它们代理到NavLink

但是当我这样做时,我得到:

警告:React 无法识别 DOM 上的 staticContext 属性 元素。如果您故意希望它作为自定义出现在 DOM 中 属性,将其拼写为小写staticcontext。如果你 不小心从父组件传递了它,将其从 DOM 中删除 元素。

可以在此处找到该问题的工作演示:

https://codesandbox.io/s/w0n49rw7kw

【问题讨论】:

【参考方案1】:

有一种克服的方法是使用:

const  to, staticContext, ...rest  = this.props;

所以你的...rest 永远不会包含staticContext

【讨论】:

【参考方案2】:

这是React documentation 中记录的简单解决方案的常见问题:

如果您尝试渲染 DOM,将触发 unknown-prop 警告 带有一个未被 React 识别为合法 DOM 的 prop 的元素 属性/属性。你应该确保你的 DOM 元素不 有虚假的道具漂浮在周围。

扩展运算符可用于从道具中提取变量,并将 剩下的 props 变成一个变量。

function MyDiv(props) 
  const  layout, ...rest  = props
  if (layout === 'horizontal') 
    return <div ...rest style=getHorizontalStyle() />
   else 
    return <div ...rest style=getVerticalStyle() />
  

您还可以将道具分配给新对象并删除键 您正在使用新对象。一定不要删除道具 原始的 this.props 对象,因为应该考虑该对象 不可变。

function MyDiv(props) 

  const divProps = Object.assign(, props);
  delete divProps.layout;

  if (props.layout === 'horizontal') 
    return <div ...divProps style=getHorizontalStyle() />
   else 
    return <div ...divProps style=getVerticalStyle() />
  

【讨论】:

【参考方案3】:

发生这种情况是因为您可能在组件的某处使用了...props

来自React的示例:

function MyDiv(props) 
  const  layout, ...rest  = props
  if (layout === 'horizontal') 
    return <div ...rest style=getHorizontalStyle() />
   else 
    return <div ...rest style=getVerticalStyle() />
  

我们单独抓取layout,这样它就不会包含在...rest中。

【讨论】:

【参考方案4】:

React 文档给出的答案对我的情况来说不够好,所以我发现/开发了一个不完美的答案,但至少不那么麻烦。

您可以在此处看到它出现的 Q/A: What is Reacts function for checking if a property applies?

要点是,使用函数为你挑选出不好的道具。

const SPECIAL_PROPS = [
    "key",
    "children",
    "dangerouslySetInnerhtml",
];

const defaultTester = document.createElement("div")
function filterBadProps(props: any, tester: HTMLElement = defaultTester) 
    if(process.env.NODE_ENV !== 'development')  return props; 

    // filter out any keys which don't exist in reacts special props, or the tester.
    const out: any = ;
    Object.keys(props).filter((propName) => 
        (propName in tester) || (propName.toLowerCase() in tester) || SPECIAL_PROPS.includes(propName)
    ).forEach((key) => out[key] = props[key]);

    return out;

就个人而言,我一开始就觉得警告完全没用,所以我添加了一行,在不处于开发模式时完全跳过检查(并且警告被抑制)。如果您觉得这些警告有价值,请删除以下行:

if(process.env.NODE_ENV !== 'development') return props;

你可以这样使用它:

public render() 
    const tooManyProps = this.props;
    const justTheRightPropsForDiv = filterBadProps(tooManyProps);
    const justTheRightPropsForSpan = filterBadProps(tooManyProps, document.createElement("span"));

    return (<div ...justTheRightPropsForDiv>
        <span ...justTheRightPropsForSpan />
    </div>)

【讨论】:

【参考方案5】:

如果有人对 react-admin 有此问题,请检查您是否没有作为 Admin 子级的链接。像这样:

<Admin layout=props => <Layout/>>
  <Link to="/something">something</Link> <-- causing issue
</Admin>

只需将其移动到另一个组件。例如,在 Layout 内部。

【讨论】:

【参考方案6】:
I got the same issue when passing data in chaild component with camelCase 
property.

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

 <CenteredModal
      moreInfo=viewType
 />

 To fix that error, i used all lowercase letters for property.
 <CenteredModal
      moreinfo=viewType
 />

【讨论】:

以上是关于React 包装器:React 无法识别 DOM 元素上的 `staticContext` 道具的主要内容,如果未能解决你的问题,请参考以下文章

React Router 中的“React 无法识别 DOM 元素上的道具”

React 无法识别 DOM 元素上的 X 属性

React 无法识别 DOM 元素上的 `toggleNode` 属性

React 无法识别 DOM 元素上的 `isActive` 属性 - styled-components

Styled-components:React 无法识别 DOM 元素上的 `lineHeight` 道具

React - 使用Jest和mock throws测试服务器请求的包装器:“错误:读取ECONNRESET”