我正在尝试诊断一个类似的问题this question, 但在这种情况下,他并不依赖wp-api-fetch
, 和我很确定我是。
我收到以下错误:
[Error] Unhandled Promise Rejection: TypeError: Object is not a function. (In \'Object(_wordpress_api_fetch__WEBPACK_IMPORTED_MODULE_5__["apiFetch"])\', \'Object\' is an instance of Object)
(完整回溯,如下所示)
我应该注意到,我对RESTAPI和ESNext/Gutenberg插件开发都是新手,所以。。。我可能遗漏了一些非常明显的东西,比如逗号:)
代码如下:
import { __ } from \'@wordpress/i18n\';
import { Fragment } from \'@wordpress/element\';
import { TextControl } from \'@wordpress/components\';
import { apiFetch } from \'@wordpress/api-fetch\';
export default function Edit( props ) {
const {
attributes: { cwraggDataSourceType, cwraggDataSource,
cwraggLocalFile },
setAttributes,
} = props;
const post_id = wp.data.select("core/editor").getCurrentPostId();
const onChangeContent = async ( newUrl ) => {
let localFileName = await apiFetch( {
path: \'/cwraggb/v1/setremotedatasrc\',
method: \'POST\',
data: { \'url\': newUrl,
\'type\': \'json\',
\'postId\': post_id } } );
...
};
...
}
我查看了
npm run start
, 它似乎包括了构建中的依赖项:
<?php return array(\'dependencies\' => array(\'wp-api-fetch\', \'wp-blocks\', \'wp-components\', \'wp-element\', \'wp-i18n\', \'wp-polyfill\'), \'version\' => \'566e4b7cb2f100542103b2b0e25aefae\');
这是在MacOS 10.15.7上构建和运行的docker。
~ % npm --version
6.14.8
~ % wp-env --version
2.1.0
知道是什么导致了错误,和/或我如何进一步诊断?
完整错误消息:
[Error] Unhandled Promise Rejection: TypeError: Object is not a function. (In \'Object(_wordpress_api_fetch__WEBPACK_IMPORTED_MODULE_5__["apiFetch"])\', \'Object\' is an instance of Object)
dispatchException (wp-polyfill.js:7017)
invoke (wp-polyfill.js:6738)
asyncGeneratorStep (cwra-google-graph-block-admin.js:250)
_next (cwra-google-graph-block-admin.js:272)
(anonymous function) (cwra-google-graph-block-admin.js:279)
Promise
(anonymous function) (cwra-google-graph-block-admin.js:268)
callCallback (react-dom.js:341)
dispatchEvent
invokeGuardedCallbackDev (react-dom.js:391)
invokeGuardedCallback (react-dom.js:448)
invokeGuardedCallbackAndCatchFirstError (react-dom.js:462)
executeDispatch (react-dom.js:594)
executeDispatchesInOrder (react-dom.js:616)
executeDispatchesAndRelease (react-dom.js:719)
forEach
forEachAccumulated (react-dom.js:699)
runEventsInBatch (react-dom.js:744)
runExtractedPluginEventsInBatch (react-dom.js:875)
handleTopLevel (react-dom.js:6026)
dispatchEventForPluginEventSystem (react-dom.js:6121)
dispatchEvent (react-dom.js:6150)
dispatchEvent
unstable_runWithPriority (react.js:2820)
discreteUpdates$1 (react-dom.js:21810)
discreteUpdates (react-dom.js:2357)
dispatchDiscreteEvent (react-dom.js:6104)
dispatchDiscreteEvent
SO网友:Tom J Nowell
根本问题是对异步函数如何工作的误解。
const onChangeContent = async ( newUrl ) => {
onChangeContent
不是函数/异步函数。这是一个目标,特别是一个承诺。
这个async
和await
都是速记。这两个功能相同:
async function foo() {
return 1
}
function foo() {
return Promise.resolve(1)
}
因为React需要一个函数,所以它得到了一个承诺,但失败了。
此外,因为如果apiFetch
调用因任何原因失败,返回的承诺上没有错误处理程序。
不仅如此,代码还被原始放置在React组件中。我强烈建议不要这样做。使用useEffect
相反,如果需要将信息传递回组件,请将其与本地状态相结合。useEffect
在呈现React组件后调用该函数,以便它不会阻止执行。它还可以防止重复不必要的呼叫。
例如,这里我们获取帖子、显示加载状态等:
import React from \'react\';
import apiFetch from \'@wordpress/api-fetch\';
import { useSelect } from \'@wordpress/data\';
import { useState, useEffect, useRef } from \'@wordpress/element\';
import { addQueryArgs } from \'@wordpress/url\';
function PostList() {
// are we loading the posts?
const [ isLoading, setLoading ] = useState( true );
// the posts we\'re displaying
const [ posts, setPosts ] = useState([]);
// we don\'t want to update state on an unmounted component
const isStillMounted = useRef();
// fetch the posts
useEffect(() => {
isStillMounted.current = true;
apiFetch( {
path: addQueryArgs( `/wp/v2/posts`, { } ),
} )
.then( ( data ) => {
if ( isStillMounted.current ) {
setPosts( data );
setLoading( false );
}
} )
.catch( () => {
if ( isStillMounted.current ) {
setPosts( [] );
setLoading( false );
}
} );
}, [setPosts, setLoading, isStillMounted]);
if ( isLoading ) {
return <div>Loading...</div>;
}
return <div>{ .. use posts variable here ... }</div>
}
请记住,这些不是特定于块编辑器的内容,它们是通用的JS React内容。
注意事项:
我们有一个catch
关于apiFetch
调用fetch调用是一种副作用,因此它被移动到useEffect
钩子(hook)
该效果在函数之外所涉及的唯一事情是更新状态,除非3个依赖项发生更改,或者安装了该组件的新实例,否则将不会再次调用该效果添加加载状态useRef
跟踪组件是否已安装。如果在API调用完成之前删除了块,则可以防止出现错误