问题描述
我是第一次使用Preact。
我只是使用preact-cli和默认模板https://github.com/preactjs-templates/default创建了一个新项目。
在app.js
中,我正在尝试使用以下代码:
import { Router } from 'preact-router';
import Header from './header';
import Home from '../routes/home';
import Profile from '../routes/profile';
// I added this function
function sleep(ms) {
return new Promise(resolve => setTimeout(resolve,ms));
}
const App = async () => { // I added "async" and the "{" in this line
await sleep(3000) // I added this line
return ( // I added this line
<div id="app">
<Header />
<Router>
<Home path="/" />
<Profile path="/profile/" user="me" />
<Profile path="/profile/:user" />
</Router>
</div>
)
} // I added this line
export default App;
但是不幸的是,浏览器给了我错误:
Uncaught Error: Objects are not valid as a child. Encountered an object with the keys {}.
为什么?
如果我不使用async/await
,它会起作用。
解决方法
免责声明:我负责Preact。
每当传递无效对象作为与预期返回类型preact/debug
不匹配的子对象(通常称为h/createElement
)时,我们的调试插件(vnode
)就会显示此错误:
const invalidVNode = { foo: 123 };
<div>{invalidVNode}</div>
在您的情况下,您的组件函数返回Promise
,这是JavaScript中的对象。当Preact渲染该组件时,渲染函数将不会返回vnode
,而是会返回Promise。这就是错误发生的原因。
提出了一个问题:
如何进行异步初始化?
一旦触发,Preact中的渲染过程始终是同步的。返回Promise
的组件会违反该合同。之所以这样,是因为在异步初始化发生时,您通常希望向用户显示至少一些东西,例如微调器。现实世界中的情况是例如通过网络获取数据。
import { useEffect } from "preact/hooks";
const App = () => {
// useEffect Hook is perfect for any sort of initialization code.
// The second parameter is for checking when the effect should re-run.
// We only want to initialize once when the component is created so we
// pass an empty array so that nothing will be dirty checked.
useEffect(() => {
doSometThingAsyncHere()
},[]);
return (
<div id="app">
<Header />
<Router>
<Home path="/" />
<Profile path="/profile/" user="me" />
<Profile path="/profile/:user" />
</Router>
</div>
)
}
,
Reactjs是一个组件库。核心功能类似于
React.createElement(component,props,...children)
第一个参数是您要渲染的组件。
放置await sleep(3000)
时,该函数未返回任何有效的child / html对象,而是返回了一个空对象。
这就是为什么您会收到此错误。