React web 中的 Javascript 函数调用
2019-02-05
137
我正在尝试从 ReactJS 调用 JS 函数。我将 MyJS.js 文件添加到 ReactJS 项目中。当我在按钮 onClick 中导入并调用 JS 函数时,例如:handleButtonColor 中的 this.abtest.events.on,当我运行 this.abtest.events.on 调用的 React 代码时,它会抛出
Uncaught TypeError: Cannot read property 'events' of undefined
。
ReactJS:
import file from './MyJS.js';
class App extends React.Component {
constructor() {
super();
this.handleButtonColor = this.handleButtonColor.bind(this);
};
render() {
return (
<CustomTemplate title="Testing Sample Reference">
<Helmet
<p><b>Testing Sample Reference A</b></p>
<div>
<button id = "expAButton" onClick = {this.handleButtonColor}>Button Experience A</button>
<button id = "expBButton" onClick = {this.handleButtonColor}>Button Experience B</button>
</div>
</CustomTemplate>
);
}
handleButtonColor() {
this.abtest.events.on('start', function (test) {
log('[start] sliced into %s for the %s test', test.slice.name, test.name);
});
this.abtest.events.on('run', function (test) {
log('[run ] "%s" test is using slice %s', test.name, test.slice.name);
});
this.abtest('expAButton', 0.75).slices('orange', 'blue').run(function () {
document.querySelector('#one').classList.add(this.slice.name);
document.querySelector('#one').textContent = '#1 ' + this.slice.name;
});
this.abtest('expBButton').slices('green', 'yellow').run(function () {
document.querySelector('#one').classList.add(this.slice.name);
document.querySelector('#one').textContent = '#1 ' + this.slice.name;
});
}
JS 代码 (MyJS.js):
(function() {
var _tests = {};
var abtest = function (testname, traffic, colorslices) {
if (_tests.hasOwnProperty(testname)) {
return _tests[testname];
}
if (typeof traffic === 'undefined') {
traffic = 1;
}
_tests[testname] = new Test(testname, traffic);
if (colorslices && colorslices.length) {
_tests[testname].slices(colorslices);
}
return _tests[testname];
};
abtest.clear = function () {
for (var test in _tests) {
if (_tests.hasOwnProperty(test)) {
_tests[test].clear();
}
}
_tests = {};
};
abtest.events = new Events();
abtest.config = {
STORAGE_PREFIX: 'ab:'
};
function Events() {
this._events = {};
}
Events.prototype.trigger = function (name) {
var args = Array.prototype.slice.call(arguments, 1);
if (this._events.hasOwnProperty(name)) {
for (var x = 0, len = this._events[name].length; x < len; x++) {
this._events[name][x].apply(window, args);
}
}
};
Events.prototype.on = function (name, callback) {
if (!this._events.hasOwnProperty(name)) {
this._events[name] = [];
}
this._events[name].push(callback);
};
function Slice (name) {
this.name = name;
}
Slice.prototype.toString = function () {
return this.name;
};
Slice.prototype.toJSON = function () {
return {
name: this.name
};
};
function Test (name, traffic) {
this.name = name;
this.traffic = traffic;
this.slice = null;
this.storage = (typeof localStorage === 'undefined') ? null : localStorage;
this._slices = {};
this._storeslice = new Slice();
}
Test.prototype.slices = function (slices) {
if (this.slice !== null) {
throw new Error('Attempted to add slices to already running test.');
}
if (Object.prototype.toString.call(slices) !== '[object Array]') {
slices = Array.prototype.slice.call(arguments, 0);
}
for (var x = 0, len = slices.length; x < len; x++) {
this.add(new Slice(slices[x])); // to add slices..
}
return this;
};
Test.prototype.add = function (slice) {
this._slices[slice.name] = slice;
return this;
};
Test.prototype.run = function (callback) {
var slice = this.urlSlice() || this.storedSlice();
if (slice && this.hasSlice(slice)) {
this.slice = this.getSlice(slice);
}
else if (Math.random() > this.traffic) {
this.slice = new Slice('commoncolor');
abtest.events.trigger('start', this);
}
else {
this.slice = this.chooseSlice();
abtest.events.trigger('start', this);
}
// Save the slice to local storage.
this.storage.setItem(this.key(), this.slice.name);
if (typeof callback === 'function') {
callback.call(this);
}
abtest.events.trigger('run', this);
return this;
};
Test.prototype.chooseSlice = function () {
var slices = [];
// Get an array of all slice names.
for (var slice in this._slices) {
if (this._slices.hasOwnProperty(slice)) {
slices.push(slice);
}
}
if (slices.length === 0) {
return new Slice('commoncolor');
}
var index = Math.floor(Math.random() / (1.0 / slices.length)); // 0.75 - "0.25 / 1 / 2"; 1 -
return this.getSlice(slices[index]);
};
Test.prototype.hasSlice = function (name) {
return (name === 'commoncolor' && this.traffic < 1) || this._slices.hasOwnProperty(name);
};
Test.prototype.getSlice = function (name) {
return name === 'commoncolor' ? new Slice('commoncolor') : this._slices[name];
};
Test.prototype.urlSlice = function () {
var hash = window.location.hash;
var search = window.location.search;
var match;
// Matches '<prefix>:<test>=<slice>'
// TOOO: Improve this regex. Define what a valid slice name is.
var re = new RegExp('(' + this.key() + ')=([\\w0-9]+)');
if (match = hash.match(re)) {
return match[2];
}
else if (match = search.match(re)) {
return match[2];
}
return false;
};
Test.prototype.storedSlice = function () {
return this.storage.getItem(this.key());
};
Test.prototype.key = function () {
return abtest.config.STORAGE_PREFIX + this.name;
};
Test.prototype.toString = function () {
return this.key();
};
Test.prototype.clear = function () {
this.storage.removeItem(this.key());
};
Test.prototype.style = function (href) {
var style = document.createElement('link');
style.rel = 'stylesheet';
style.href = href;
document.head.appendChild(style);
return this;
};
Test.prototype.script = function (src, async) {
var script = document.createElement('script');
script.type = 'text/javascript';
script.async = (typeof async === 'undefined') ? true : !!async;
script.src = src;
var firstScript = document.getElementsByTagName('script')[0];
firstScript.parentNode.insertBefore(script, firstScript);
return this;
};
abtest.Test = Test;
abtest.Slice = Slice;
abtest.Storage = (typeof localStorage === 'undefined') ? null : Storage;
abtest.Events = Events;
if (typeof module !== 'undefined' && module.exports && typeof require !== 'undefined') {
module.exports = abtest;
}
else if (typeof define === 'function' && define.amd) {
define('ab', function () {
return abtest;
});
}
else {
window.abtest = abtest;
}
})();
2个回答
React 语法是错误的,但我假设您只展示了代码的相关部分。
对于您
render()
某些内容,它应该是扩展
React.Component
基类的类。
此外,
this
仅限于访问函数执行的动态范围内的值(可以使用
bind
、
call
或
apply
进行修改)
在您的特定场景中,
this.abtest
将未定义。
您可以尝试使用
window.abtest
,因为它作为全局变量添加到您的其他文件中
Dhananjai Pai
2019-02-05
我修复了这个问题。谢谢。我在 JS 顶级函数中使用了导出。并从 React 中导入它。
user1953977
2019-02-07