首页 > 解决方案 > ReactJS 错误:确保传递与组件的构造函数相同的道具

问题描述

我正在学习“清晰”的 ReactJS(即它不是 JSX)。这是我的简单代码:

(() => {
    class List extends React.Component{
        constructor({tag, attributes, items}){
            super({tag, attributes, items})
            this.tag = tag
            this.attributes = attributes
            this.items = items
        }
        render(){
            return React.createElement(this.props.tag, this.props.attributes, items.map(
                (n, i) => new React.createElement(ListItem, 
                    { attributes: { ...n.attributes, key: i }, value: n.value })))
        }
    }

    class ListItem extends React.Component{
        constructor({attributes, value}){
            super({attributes, value})
            this.attributes = attributes
            this.value = value
        }
        render(){
            return React.createElement("li", this.props.attributes, this.props.value)
        }
    }

    const items = [
        { attributes: null, value: "A" },
        { attributes: null, value: "B" },
        { attributes: null, value: "C" },
        { attributes: null, value: "D" },
        { attributes: null, value: "E" }
    ]

    const root = document.getElementById("root")

    ReactDOM.render(new React.createElement(List, { tag: "ul", attributes: null, items }), root)
})()

请注意:我放入了super与组件构造函数中相同的参数。我也key用于li元素。但我得到这样的错误:

警告:List(...):在调用 super() 时List,请确保传递与传递组件构造函数相同的道具。

警告:数组或迭代器中的每个孩子都应该有一个唯一的“key”道具。

检查List.

在 ListItem(由 List 创建)

在列表中

警告:ListItem(...):在调用 super() 时ListItem,请确保传递与传递组件的构造函数相同的道具。警告:ListItem(...):在调用 super() 时ListItem,请确保传递与传递组件的构造函数相同的道具。警告:ListItem(...):在调用 super() 时 ListItem,请确保传递与传递组件的构造函数相同的道具。警告:ListItem(...):在调用 super() 时ListItem,请确保传递与传递组件的构造函数相同的道具。警告:ListItem(...):在调用 super() 时ListItem,请确保传递与传递组件的构造函数相同的道具。

我做错了什么?

标签: javascriptreactjs

解决方案


例如,您需要使用单个变量props作为constructor函数的参数。然后将其传递给super. 下面的代码修复了所有警告。

class List extends React.Component {
  constructor(props) {
    super(props);
    this.tag = props.tag;
    this.attributes = props.attributes;
    this.items = props.items;
  }
  render() {
    return React.createElement(
      this.props.tag,
      this.props.attributes,
      items.map(
        (n, i) =>
          new React.createElement(ListItem, {
            attributes: { ...n.attributes, key: i },
            value: n.value
          })
      )
    );
  }
}

class ListItem extends React.Component {
  constructor(props) {
    super(props);
    this.attributes = props.attributes;
    this.value = props.value;
  }
  render() {
    return React.createElement("li", this.props.attributes, this.props.value);
  }
}

const items = [
  { attributes: null, value: "A" },
  { attributes: null, value: "B" },
  { attributes: null, value: "C" },
  { attributes: null, value: "D" },
  { attributes: null, value: "E" }
];

const root = document.getElementById("root");

ReactDOM.render(
  new React.createElement(List, { tag: "ul", attributes: null, items }),
  root
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
	<div id="root"></div>

官方文档类组件应该总是用props.

当我查看源代码时:

const hasMutatedProps = instance.props !== newProps;
warningWithoutStack(
    instance.props === undefined || !hasMutatedProps,
      '%s(...): When calling super() in `%s`, make sure to pass ' +
      "up the same props that your component's constructor was passed.",
      name,
      name,
  );

似乎反应检查props它在函数中收到的对象是否与您使用或不constructor传递给基类的对象相同。super()在您的代码中,当然不一样。你传递给super({attributes, value})例如完全不同的对象。因为在 JS 中:

{a: 1, b: 2} === {a:1, b:2} // false
{a: 1, b: 2} !== {a:1, b:2} // true

推荐阅读