我正在努力寻找使用Suspense和React hooks 的问题。
下面的 React 代码有几个关键问题。
import { Suspense, useState, useEffect } from 'react';
const SuspensefulUserProfile = ({ userId }) => {
const [data, setData] = useState({});
useEffect(() => {
fetchUserProfile(userId).then((profile) => setData(profile));
}, [userId, setData])
return (
<Suspense>
<UserProfile data={data} />
</Suspense>
);
};
const UserProfile = ({ data }) => {
return (
<>
<h1>{data.name}</h1>
<h2>{data.email}</h2>
</>
);
};
const UserProfileList = () => {
<>
<SuspensefulUserProfile userId={1} />
<SuspensefulUserProfile userId={2} /> …Run Code Online (Sandbox Code Playgroud) 我正在构建一个应用程序来展示 Nextjs 13 中 Suspense 的用法。但是加载时 Suspense 回退并未显示。
这是page.js
import React, { Suspense } from "react";
import Loading from "./loading";
const Trending = React.lazy(() => import("./Trending"));
function Page() {
return (
<div>
<Suspense fallback={<Loading />}>
<Trending />
</Suspense>
</div>
);
}
export default Page;
Run Code Online (Sandbox Code Playgroud)
这里是流行趋势
import axios from "axios";
export default async function Trending() {
const res = await axios.get(
`https://api.themoviedb.org/3/trending/movie/day?api_key=1428e09fe38be9df57355a8d6198d916`
);
const data = res.data;
// Add a delay to ensure that the Suspense fallback is shown
await new …Run Code Online (Sandbox Code Playgroud) 我知道 Suspense 组件是 React-ian代码拆分方法,它使网页加载速度更快。现在,假设您有一个像这样的组件层次结构:
<App>
<Suspense fallback={<FirstLoader/>}>
<OuterWrapper>
<Suspense fallback={<SecondLoader/>}>
<InnerWrapper>
{content}
</InnerWrapper>
</Suspense>
</OuterWrapper>
</Suspense>
</App>
Run Code Online (Sandbox Code Playgroud)
首先假设只有InnerWrapper延迟加载,在第二种情况下它们都是延迟加载的。
React 是在加载InnerWrapper后延迟OuterWrapper加载,还是同时加载?具体来说,是否在加载第一个组件后推迟渲染第二个 Suspense 的回退。
我正在使用此博客文章<React.Suspense>中的数据获取。\n来自反应文档
\n\nSuspense 让你的组件在渲染之前等待一些东西。
\n
本文档中有更好的解释
\n\n\n\n
React.Suspense允许您指定加载指示器,以防其下方树中的某些组件尚未准备好渲染
我了解到,<React.Suspense>如果组件尚未准备好渲染,则会显示指定为后备属性的加载指示器。
但是我不明白 React 如何检查组件是否准备好渲染。根据这个文档
\n\n\n随着更多的数据流入,React 将重试渲染,每次它都可能能够进行 \xe2\x80\x9cdeeper\xe2\x80\x9d。
\n
这是否意味着当数据从网络请求流入时,React 也会重新渲染?
\n并<React.Suspense>不断检查组件是否准备好渲染?
这是我的设置:
const DesktopApp = lazy(() => import(/* webpackChunkName: "DesktopApp" */'./DesktopApp'));
const MobileApp = lazy(() => import(/* webpackChunkName: "MobileApp" */'./MobileApp'));
type Props = { shouldServeMobile: boolean };
export const App = ({ shouldServeMobile }: Props): JSX.Element => (
shouldServeMobile
? (
<Suspense fallback={<AppLoading />}>
<MobileApp />
</Suspense>
) : (
<Suspense fallback={<AppLoading />}>
{/* GlobalDesktopStyle is injected in multiple places due to a bug where the
theme gets reset when lazy loading via React.Lazy + webpack */}
<GlobalDesktopStyle />
<DesktopApp /> …Run Code Online (Sandbox Code Playgroud) reactjs webpack webpack-dev-server react-hot-loader react-suspense
我在动态路由上使用了 react lazy 和 suspense,但不知何故我无法渲染延迟加载的组件。
我已经搜索了关于在路由上使用 lazy 的信息,但我还没有看到有人在动态(localhost:8080/ dynamic / dynamic)路由上使用它。
在动态路由上加载组件对我有用,如果我有静态路由,延迟加载也适用,但是当我尝试将两者结合时,组件不会加载。
这是我所做的一个例子,
import Loader from './path/toFile';
import Home from './path/toFile';
const LazyLoadedComponent = lazy(() => import('./path/toFile'));
const App = () => {
return(
<Router>
<Switch>
// Home has multiple views controlled by buttons
// A view contains selections with corresponding id
<Route exact path="/:viewType?" component={Home} />
// this component doesn't load when I select something which links me to this dynamic route.
<Suspense fallback={Loader}>
<Route path="/viewType/:selectionId" component={LazyLoadedComponent} /> …Run Code Online (Sandbox Code Playgroud) 使用 es6 导入,您可以执行以下操作:
import { MyComponent } from "../path/to/components.js";
export default function () {
return <MyComponent/>;
}
Run Code Online (Sandbox Code Playgroud)
我也可以这样做React.lazy吗?
const { MyComponent } = lazy(() => import("../path/to/components.js"));
Run Code Online (Sandbox Code Playgroud)
我收到以下错误,但我不确定它是否与此错误或我遇到的其他错误有关:
元素类型无效:应为字符串(对于内置组件)或类/函数(对于复合组件)但得到:未定义
我想延迟加载我的组件以减少我的初始包大小并使用 react router 使用代码拆分来动态获取组件。
但是,在使用 React Suspense 时,它们会强制您使用回退进行加载。
这行不通:
const lazyLoadComponent = Component =>
props => (
<Suspense> // Missing fallback property
<Component {...props} />
</Suspense>
);
Run Code Online (Sandbox Code Playgroud)
在我的情况下,我从服务器渲染 html,所以我不想使用微调器。
这会在我的屏幕上产生无用的闪烁!IE:
在我的情况下,html 对应于加载的 react 组件。
是否有任何已知的 hack 可以轻松解决此问题(除了为复制 html (!!) 的任何路由创建加载程序,顺便说一下,这会使延迟加载无用)。
我对“强迫”我们添加加载器有点不满意,我不明白强制执行的决定背后的逻辑。
我正在使用 react-18next 在整个 React 应用程序中加载翻译。我在让我的应用程序等待翻译时遇到问题。这打破了我们在 Jenkins 中的测试,因为他们在许多情况下都在搜索已翻译的密钥。
i18n.tsx:
i18n
.use(initReactI18next)
.init({
resources, // set ressources to be used
lng: "en", // set default language
keySeparator: false,
interpolation: {
escapeValue: false
},
react: {
useSuspense: false,
}
});
Run Code Online (Sandbox Code Playgroud)
注意:我尝试使用 Suspense 和不使用 Suspense,useSuspense 标志与尝试匹配(真/默认为 Suspense)。
尝试准备:
const SiteLabel: React.FunctionComponent<ISiteLabelProps> = (props) => {
const { t, ready } = useTranslation(undefined, {
useSuspense: false
});
const getTo = (): string => {
return "/" + props.module.toLowerCase();
}
const getLabel = (): string => …Run Code Online (Sandbox Code Playgroud) 我正在开发一个应用程序,如果下一页有任何尚未加载的延迟加载组件,我们希望在页面之间进行转换。所以我想弄清楚是否有任何方法可以可靠地检查延迟加载的组件是否已完成加载。
此解决方案有效,但仅在延迟加载的组件第一次尝试加载时才有效——即如果它立即呈现则无效,因为延迟加载的组件已经加载。
import React, {PropsWithChildren, useEffect} from 'react'
export default function SuspenseTrigger(props) {
return (
<React.Suspense fallback={
<>
{props.fallback}
<Trigger onLoad={props.onLoad} onComplete={props.onComplete} />
</>
}>
{props.children}
</React.Suspense>
)
}
function Trigger(props) {
useEffect(() => {
if (props.onLoad) {
props.onLoad()
}
return () => {
if (props.onComplete) {
setTimeout(props.onComplete)
}
}
}, [])
return <></>
}
Run Code Online (Sandbox Code Playgroud)
此组件调用正确onLoad和onComplete第一次它的加载。然而,在随后的时间里,因为延迟加载的组件现在被缓存,子组件会立即呈现,onLoad并且onComplete永远不会呈现回退,这意味着永远不会被调用。
我尝试过的一件事是将第二个Trigger放在 的主体中SuspenseTrigger:
function ensureLoadCompleteCalled() {
onLoad()
onComplete() …Run Code Online (Sandbox Code Playgroud) javascript reactjs react-hooks react-suspense react-lazy-load
react-suspense ×10
reactjs ×10
javascript ×4
react-hooks ×2
react-router ×2
asynchronous ×1
lazy-loading ×1
next.js ×1
next.js13 ×1
typescript ×1
webpack ×1