在 React 中扩充对象

Augmenting Object in React

我正在做一个项目,我必须将一些实用函数附加到 Javascript Object 对象,如下所示:

function isEmpty(a, b) {...}
Object.prototype.isEmpty = isEmpty;

现在我面临的问题是,因为我正在使用 React,所以我猜测上面的代码也将 isEmpty 函数附加到构造的组件。只要我不在我的组件中使用本机 html 标签,即 divspan,这就可以正常工作,这是不可能的。我收到以下警告

Warning: Unknown prop `isEmpty` on <div> tag. 
Remove these props from the element. For details, see
https://facebook.github.io/react/warnings/unknown-prop.html

当我使用本机 html 标签时。有什么方法可以扩充 Object 对象而不会在反应中出现此错误?

当您在 React 中编写 jsx 标签时,它会被转换为对象(React 元素)。

所以

<div id="test">
</div>

转化为如下object-

var divElement = React.createElement("div", { id: "test" });

既然你正在附加

function sum(a, b) {...}
Object.prototype.sum = sum;

它会附加到存在的每个对象上。

也许您应该考虑提供一个 Util.js,它将包含所有实用方法并且不附加到对象原型。因为它会导致不良的副作用。

您可以在任何需要的地方导入 Util.js 并使用这些方法。

例如-

module.exports = {
    sum(a, b) {...}
};

问题

所有 JSX 元素首先创建为对象(WitVault 解释了如何将 JSX 转换为可以在浏览器中 运行 的普通 JS)。 React 获取 React 支持的那些对象及其属性,并将它们映射到 DOM 元素。如果有 React 不知道的属性,它会显示警告,因为它可能是 "you don't know what you are doing" 或 "you made a typo" 的情况,因此您不会得到您期望的行为。

由于您编辑了 Object 的原型,所有对象,包括 React 创建的对象,都得到 属性 sum,对于原始 html 元素,React 不知道如何地图 sum 属性.

正如 Juan Mendes 指出的那样,extending native objects is bad practice。如果你在 React 项目中扩展 Object.prototype 你真的无法避免你遇到的问题。

解决方案 1:Export/Import util 函数

由于 React 带有 browserify,因此您可以改为导入实​​用程序方法。这有两个好处:

  • 您不需要扩展本机对象
  • 您清楚地表达了所用方法的来源,因为它们在使用它的文件中有导入语句。

在 ES6 中

// util/objectSum.js
export default function objectSum(object) { ... };

// anotherFile.js
import objectSum from 'utils/objectSum.js'; // assuming utils/ is directly under the root path of your project (root path can be configured in webpack.config if you use webpack)

const object = ?; // the object you want to sum
const sum = objectSum(object);

在 ES5 中

// util/objectSum.js
module.exports = function(object) { ... };

// anotherFile.js
var objectSum = require('utils/objectSum.js'); // assuming utils/ is directly under the root path of your project (root path can be configured in webpack.config if you use webpack)

const object = ?; // the object you want to sum
const sum = objectSum(object);

解决方案 2:使用 ES6 classes

在 ES6 中,您还可以使用 sum 方法创建 class。这是一个例子:

class NumberList {
    constructor(arrayOfNumbers) {
        this.numbers = arrayOfNumbers;
        this.sum = this.sum.bind(this);
    }

    sum() {
        return this.numbers.reduce((sum, next) => sum + next, 0);
    }
}

const numberList = new NumberList([1, 2, 3]);
numberList.sum(); // -> 6

问题是像这样的对象扩展是可枚举的。您需要使用 defineProperty

顺便说一句:这仍然是个坏主意