React 对象不是 useEffect 上的函数错误
我在此功能组件中使用 useEffect 钩子时遇到问题。我收到一个对象不是函数的错误。
我发现这个错误经常出现在 camelCase 命名的功能组件中,但是,这是一个 PascalCase 命名的功能组件。
如果您能发现错误,请告诉我。这是来自 udemy 的 React 教程,所以请原谅我的菜鸟 :)
编辑:我确认在注释掉 useEffect 时,组件的呈现没有问题
编辑 2:为了确保没有任何语法错误,我创建了一个 toBeExecuted 函数,然后将其作为 useEffect 的参数传递(尝试仅传递方法名称以及调用它),但错误仍然存​​在
$ npm view react version 16.13.1
import React, { useEffect } from "react";
import classes from "./Cockpit.css";
const Cockpit = (props) => {
useEffect(() => {
console.log("shd");
setTimeout(() => {
alert("Saved data to cloud!");
}, 1000);
return () => {
console.log('[Cockpit.js] cleanup work in use')
}
}, [props.persons]);
const assignedClasses = [];
let btnClass = "";
if (props.showPersons) {
btnClass = classes.Red;
}
if (props.persons.length <= 2) {
assignedClasses.push(classes.red); // classes = ['red']
}
if (props.persons.length <= 1) {
assignedClasses.push(classes.bold); // classes = ['red', 'bold']
}
return (
<div className={classes.Cockpit}>
<h1>{props.title}</h1>
<p className={assignedClasses.join(" ")}>This is really working!</p>
<button className={btnClass} onClick={props.clicked}>
Toggle Persons
</button>
</div>
);
};
export default Cockpit;
以下是控制台错误
Uncaught TypeError: Object(...) is not a function
at Cockpit (Cockpit.js:6)
at mountIndeterminateComponent (react-dom.development.js:10449)
at beginWork (react-dom.development.js:10647)
at performUnitOfWork (react-dom.development.js:12621)
at workLoop (react-dom.development.js:12730)
at HTMLUnknownElement.callCallback (react-dom.development.js:1319)
at Object.invokeGuardedCallbackDev (react-dom.development.js:1358)
at invokeGuardedCallback (react-dom.development.js:1215)
at performWork (react-dom.development.js:12848)
at scheduleUpdateImpl (react-dom.development.js:13233)
at scheduleUpdate (react-dom.development.js:13172)
at scheduleTopLevelUpdate (react-dom.development.js:13445)
at Object.updateContainer (react-dom.development.js:13475)
at react-dom.development.js:17168
at Object.unbatchedUpdates (react-dom.development.js:13304)
at renderSubtreeIntoContainer (react-dom.development.js:17167)
at Object.render (react-dom.development.js:17192)
at Object../src/index.js (index.js:7)
at __webpack_require__ (bootstrap 27db9ccab8c2fd790147:669)
at fn (bootstrap 27db9ccab8c2fd790147:87)
at Object.0 (registerServiceWorker.js:108)
at __webpack_require__ (bootstrap 27db9ccab8c2fd790147:669)
at bootstrap 27db9ccab8c2fd790147:715
at bundle.js:719
以下是浏览器错误
×
TypeError: Object(...) is not a function
Cockpit
C:/react course/module 7/debugging--01-finished/src/components/Cockpit/Cockpit.js:6
3 | import classes from "./Cockpit.css";
4 |
5 | const Cockpit = (props) => {
> 6 | useEffect(() => {
7 | console.log("shd");
8 | setTimeout(() => {
9 | alert("Saved data to cloud!");
View compiled
mountIndeterminateComponent
C:/react course/module 7/debugging--01-finished/node_modules/react-dom/cjs/react-dom.development.js:10449
10446 |
10447 | {
10448 | ReactCurrentOwner$2.current = workInProgress;
> 10449 | value = fn(props, context);
10450 | }
10451 | // React DevTools reads this flag.
10452 | workInProgress.effectTag |= PerformedWork$1;
View compiled
beginWork
C:/react course/module 7/debugging--01-finished/node_modules/react-dom/cjs/react-dom.development.js:10647
10644 |
10645 | switch (workInProgress.tag) {
10646 | case IndeterminateComponent$2:
> 10647 | return mountIndeterminateComponent(current, workInProgress, priorityLevel);
10648 | case FunctionalComponent$1:
10649 | return updateFunctionalComponent(current, workInProgress);
10650 | case ClassComponent$6:
View compiled
performUnitOfWork
C:/react course/module 7/debugging--01-finished/node_modules/react-dom/cjs/react-dom.development.js:12621
12618 | {
12619 | startWorkTimer(workInProgress);
12620 | }
> 12621 | var next = beginWork(current, workInProgress, nextPriorityLevel);
12622 | if (true && ReactFiberInstrumentation$1.debugTool) {
12623 | ReactFiberInstrumentation$1.debugTool.onBeginWork(workInProgress);
12624 | }
View compiled
workLoop
C:/react course/module 7/debugging--01-finished/node_modules/react-dom/cjs/react-dom.development.js:12730
12727 | if (nextPriorityLevel <= TaskPriority$1) {
12728 | // Flush all synchronous and task work.
12729 | while (nextUnitOfWork !== null) {
> 12730 | nextUnitOfWork = performUnitOfWork(nextUnitOfWork);
12731 | if (nextUnitOfWork === null) {
12732 | !(pendingCommit !== null) ? invariant(false, 'Should have a pending commit. This error is likely caused by a bug in React. Please file an issue.') : void 0;
12733 | // We just completed a root. Commit it now.
View compiled
HTMLUnknownElement.callCallback
C:/react course/module 7/debugging--01-finished/node_modules/react-dom/cjs/react-dom.development.js:1319
1316 | // nested call would trigger the fake event handlers of any call higher
1317 | // in the stack.
1318 | fakeNode.removeEventListener(evtType, callCallback, false);
> 1319 | func.apply(context, funcArgs);
1320 | didError = false;
1321 | }
1322 |
View compiled
invokeGuardedCallbackDev
C:/react course/module 7/debugging--01-finished/node_modules/react-dom/cjs/react-dom.development.js:1358
1355 | // errors, it will trigger our global error handler.
1356 | var evt = document.createEvent('Event');
1357 | evt.initEvent(evtType, false, false);
> 1358 | fakeNode.dispatchEvent(evt);
1359 |
1360 | if (didError) {
1361 | if (!didSetError) {
View compiled
invokeGuardedCallback
C:/react course/module 7/debugging--01-finished/node_modules/react-dom/cjs/react-dom.development.js:1215
1212 | * @param {...*} args Arguments for function
1213 | */
1214 | invokeGuardedCallback: function (name, func, context, a, b, c, d, e, f) {
> 1215 | invokeGuardedCallback.apply(ReactErrorUtils, arguments);
1216 | },
1217 |
1218 | /**
View compiled
performWork
C:/react course/module 7/debugging--01-finished/node_modules/react-dom/cjs/react-dom.development.js:12848
12845 | var didError = false;
12846 | var error = null;
12847 | {
> 12848 | invokeGuardedCallback$1(null, workLoop, null, minPriorityLevel, deadline);
12849 | if (hasCaughtError()) {
12850 | didError = true;
12851 | error = clearCaughtError();
View compiled
scheduleUpdateImpl
C:/react course/module 7/debugging--01-finished/node_modules/react-dom/cjs/react-dom.development.js:13233
13230 | performWork(SynchronousPriority$1, null);
13231 | } else {
13232 | // Flush both synchronous and task work.
> 13233 | performWork(TaskPriority$1, null);
13234 | }
13235 | break;
13236 | case TaskPriority$1:
View compiled
scheduleUpdate
C:/react course/module 7/debugging--01-finished/node_modules/react-dom/cjs/react-dom.development.js:13172
13169 | }
13170 |
13171 | function scheduleUpdate(fiber, priorityLevel) {
> 13172 | return scheduleUpdateImpl(fiber, priorityLevel, false);
13173 | }
13174 |
13175 | function scheduleUpdateImpl(fiber, priorityLevel, isErrorRecovery) {
View compiled
scheduleTopLevelUpdate
C:/react course/module 7/debugging--01-finished/node_modules/react-dom/cjs/react-dom.development.js:13445
13442 | warning$18(callback === null || typeof callback === 'function', 'render(...): Expected the last optional `callback` argument to be a ' + 'function. Instead received: %s.', callback);
13443 | }
13444 | addTopLevelUpdate(current, nextState, callback, priorityLevel);
> 13445 | scheduleUpdate(current, priorityLevel);
13446 | }
13447 |
13448 | return {
View compiled
updateContainer
C:/react course/module 7/debugging--01-finished/node_modules/react-dom/cjs/react-dom.development.js:13475
13472 | container.pendingContext = context;
13473 | }
13474 |
> 13475 | scheduleTopLevelUpdate(current, element, callback);
13476 | },
13477 |
13478 |
View compiled
(anonymous function)
C:/react course/module 7/debugging--01-finished/node_modules/react-dom/cjs/react-dom.development.js:17168
17165 | root = container._reactRootContainer = newRoot;
17166 | // Initial mount should not be batched.
17167 | DOMRenderer.unbatchedUpdates(function () {
> 17168 | DOMRenderer.updateContainer(children, newRoot, parentComponent, callback);
17169 | });
17170 | } else {
17171 | DOMRenderer.updateContainer(children, root, parentComponent, callback);
View compiled
unbatchedUpdates
C:/react course/module 7/debugging--01-finished/node_modules/react-dom/cjs/react-dom.development.js:13304
13301 | isUnbatchingUpdates = isBatchingUpdates;
13302 | isBatchingUpdates = false;
13303 | try {
> 13304 | return fn();
13305 | } finally {
13306 | isBatchingUpdates = previousIsBatchingUpdates;
13307 | isUnbatchingUpdates = previousIsUnbatchingUpdates;
View compiled
renderSubtreeIntoContainer
C:/react course/module 7/debugging--01-finished/node_modules/react-dom/cjs/react-dom.development.js:17167
17164 | var newRoot = DOMRenderer.createContainer(container);
17165 | root = container._reactRootContainer = newRoot;
17166 | // Initial mount should not be batched.
> 17167 | DOMRenderer.unbatchedUpdates(function () {
17168 | DOMRenderer.updateContainer(children, newRoot, parentComponent, callback);
17169 | });
17170 | } else {
View compiled
render
C:/react course/module 7/debugging--01-finished/node_modules/react-dom/cjs/react-dom.development.js:17192
17189 | return renderSubtreeIntoContainer(null, element, container, true, callback);
17190 | },
17191 | render: function (element, container, callback) {
> 17192 | return renderSubtreeIntoContainer(null, element, container, false, callback);
17193 | },
17194 | unstable_renderSubtreeIntoContainer: function (parentComponent, element, containerNode, callback) {
17195 | !(parentComponent != null && ReactInstanceMap_1.has(parentComponent)) ? invariant(false, 'parentComponent must be a valid React Component') : void 0;
View compiled
./src/index.js
C:/react course/module 7/debugging--01-finished/src/index.js:7
4 | import App from './containers/App';
5 | import registerServiceWorker from './registerServiceWorker';
6 |
> 7 | ReactDOM.render(<App appTitle="Person Manager" />, document.getElementById('root'));
8 | registerServiceWorker();
9 |
10 |
View compiled
__webpack_require__
C:/react course/module 7/debugging--01-finished/webpack/bootstrap 27db9ccab8c2fd790147:669
666 | };
667 |
668 | // Execute the module function
> 669 | modules[moduleId].call(module.exports, module, module.exports, hotCreateRequire(moduleId));
670 |
671 | // Flag the module as loaded
672 | module.l = true;
View compiled
fn
C:/react course/module 7/debugging--01-finished/webpack/bootstrap 27db9ccab8c2fd790147:87
84 | console.warn("[HMR] unexpected require(" + request + ") from disposed module " + moduleId);
85 | hotCurrentParents = [];
86 | }
> 87 | return __webpack_require__(request);
88 | };
89 | var ObjectFactory = function ObjectFactory(name) {
90 | return {
View compiled
0
http://localhost:3000/static/js/bundle.js:63759:18
__webpack_require__
C:/react course/module 7/debugging--01-finished/webpack/bootstrap 27db9ccab8c2fd790147:669
666 | };
667 |
668 | // Execute the module function
> 669 | modules[moduleId].call(module.exports, module, module.exports, hotCreateRequire(moduleId));
670 |
671 | // Flag the module as loaded
672 | module.l = true;
View compiled
(anonymous function)
C:/react course/module 7/debugging--01-finished/webpack/bootstrap 27db9ccab8c2fd790147:715
712 | __webpack_require__.h = function() { return hotCurrentHash; };
713 |
714 | // Load entry module and return exports
> 715 | return hotCreateRequire(0)(__webpack_require__.s = 0);
716 |
717 |
718 |
View compiled
(anonymous function)
http://localhost:3000/static/js/bundle.js:719:10
This screen is visible only in development. It will not appear if the app crashes in production.
Open your browser’s developer console to further inspect this error.
以下是我的 package.json
{
"name": "react-complete-guide",
"version": "0.1.0",
"private": true,
"dependencies": {
"autoprefixer": "7.1.2",
"babel-core": "6.25.0",
"babel-eslint": "7.2.3",
"babel-jest": "20.0.3",
"babel-loader": "7.1.1",
"babel-preset-react-app": "^3.0.2",
"babel-runtime": "6.26.0",
"case-sensitive-paths-webpack-plugin": "2.1.1",
"chalk": "1.1.3",
"css-loader": "0.28.4",
"dotenv": "4.0.0",
"eslint": "4.4.1",
"eslint-config-react-app": "^2.0.0",
"eslint-loader": "1.9.0",
"eslint-plugin-flowtype": "2.35.0",
"eslint-plugin-import": "2.7.0",
"eslint-plugin-jsx-a11y": "5.1.1",
"eslint-plugin-react": "7.1.0",
"extract-text-webpack-plugin": "3.0.0",
"file-loader": "0.11.2",
"fs-extra": "3.0.1",
"html-webpack-plugin": "2.29.0",
"jest": "20.0.4",
"object-assign": "4.1.1",
"postcss-flexbugs-fixes": "3.2.0",
"postcss-loader": "2.0.6",
"promise": "8.0.1",
"radium": "^0.19.4",
"react": "^16.0.0-rc.3",
"react-dev-utils": "^4.0.1",
"react-dom": "^16.0.0-rc.3",
"style-loader": "0.18.2",
"sw-precache-webpack-plugin": "0.11.4",
"url-loader": "0.5.9",
"webpack": "3.5.1",
"webpack-dev-server": "2.7.1",
"webpack-manifest-plugin": "1.2.1",
"whatwg-fetch": "2.0.3"
},
"scripts": {
"start": "node scripts/start.js",
"build": "node scripts/build.js",
"test": "node scripts/test.js --env=jsdom"
},
"jest": {
"collectCoverageFrom": [
"src/**/*.{js,jsx}"
],
"setupFiles": [
"<rootDir>/config/polyfills.js"
],
"testMatch": [
"<rootDir>/src/**/__tests__/**/*.js?(x)",
"<rootDir>/src/**/?(*.)(spec|test).js?(x)"
],
"testEnvironment": "node",
"testURL": "http://localhost",
"transform": {
"^.+\\.(js|jsx)$": "<rootDir>/node_modules/babel-jest",
"^.+\\.css$": "<rootDir>/config/jest/cssTransform.js",
"^(?!.*\\.(js|jsx|css|json)$)": "<rootDir>/config/jest/fileTransform.js"
},
"transformIgnorePatterns": [
"[/\\\\]node_modules[/\\\\].+\\.(js|jsx)$"
],
"moduleNameMapper": {
"^react-native$": "react-native-web"
},
"moduleFileExtensions": [
"web.js",
"js",
"json",
"web.jsx",
"jsx",
"node"
]
},
"babel": {
"presets": [
"react-app"
]
},
"eslintConfig": {
"extends": "react-app"
}
}
我已经在 Codesandbox 中使用它了: https://codesandbox.io/s/stackoverflow--useeffect-qzg3z?fontsize=14&hidenavigation=1&theme=dark
为了演示,我将上面的
props
值提升为常量。我虚构了一些值,但这些值在您的代码中并不清楚。
我猜想它是
props.clicked
的值,位于
<button className={btnClass} onClick={props.clicked}>
也许是
console.log(props.clicked)
,然后看看它以什么形式出现?
编辑:我通过将
clicked
替换为
{
进行了测试,它引发了一个错误,但它与您看到的错误不同。所以,我认为我的预感是错误的。抱歉 :(
另一个错误(可能不相关)是您使用大写“R”
classes.Red
和小写“r”
classes.red
。您没有共享该对象,所以我不确定哪个是正确的。
最后,一个标注。您可能不需要将
props.persons
作为依赖项数组传递给
useEffect
。有时我想强制重新渲染与正在使用的数据无关,但这种情况非常罕见。通常,您的依赖项数组围绕
useEffect
内部使用的数据,并且您不使用
props.persons
。我猜你正在做一个教程,所以也许会改变。