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

IT技术 reactjs react-router react-router-dom
2021-03-30 18:17:48

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

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

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

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

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

6个回答

有一种克服方法是使用:

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

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

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

如果您尝试使用 React 未识别为合法 DOM 属性/属性的 prop 来渲染 DOM 元素,则会触发 unknown-prop 警告。你应该确保你的 DOM 元素没有浮动的虚假props。

扩展运算符可用于将变量从 props 中拉出,并将剩余的 props 放入变量中。

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

您还可以将props分配给新对象并从新对象中删除您正在使用的键。确保不要从原始 this.props 对象中删除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()} />
  }
}

发生这种情况是因为您可能{...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}.

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

你可以在这里看到它出现的 Q/A: What is Reacts function for checks if a property apply?

要点是,使用一个函数为你挑选出不好的props。

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

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

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

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

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

只需将其移动到另一个组件即可。例如,在布局内部。