reactjs - React:防止子组件在获取数据之前进行渲染
问题描述
我正在尝试制作一个包装器组件来显示加载微调器、错误消息或子组件,具体取决于是否在 React 中获取了数据。然而,即使页面正在加载(this.state.loading === true
)意味着不应该渲染子内容,React 仍然以某种方式渲染或处理子组件,并且会抛出错误Cannot read property 'useRoundedImages' of undefined
。
// page.js
export default class Page extends Component {
constructor(props) {
super(props)
this.state = {
loading: true,
error: undefined,
user: undefined,
};
}
componentDidMount() {
getData(...).then(res => {
this.setState({ loading: false, user: res.data.user});
});
}
render() {
return (
<LoadWrapper loading={this.state.loading} error={this.state.error}>
<p>{this.state.user.options.useRoundedImages}</p>
</LoadWrapper>
);
}
}
}
// loading-wrapper.js
export default class LoadWrapper extends Component {
render() {
return (
this.props.loading ? <Spinner animation="border" className="mx-auto d-block" /> :
this.props.error ? <ErrorPage error={this.props.error}></ErrorPage> :
<>{this.props.children}</>
);
}
}
如何防止渲染这些元素,或者有更好的方法有条件地渲染我的加载微调器、错误消息和子组件?
解决方案
我认为问题来了:
<LoadWrapper loading={this.state.loading} error={this.state.error}>
<p>{this.state.user?.options.useRoundedImages}</p>
</LoadWrapper>
这里的问题是Page
组件内部的每一行。你的LoadWrapper
逻辑是正确的。但是,当您Page
的组件渲染时,它会出现在每一行中,因此这意味着您的LoadWrapper
遗嘱不会生成子组件,但您的Page
组件会出现在每一行中,这就是它给出此错误的原因,因为当时没有任何user
价值。Cannot read property 'useRoundedImages' of undefined
. 您可以使用可选链接来防止这种情况
在这里,我复制了您的逻辑并创建了 POC。希望您了解上下文:代码:
import React, { Component } from "react";
import "./styles.css";
class LoadWrapper extends Component {
render() {
if (this.props.loading) {
return <>Loading...</>;
} else if (this.props.error) {
return <>Error....</>;
} else {
return <>{this.props.children}</>;
}
}
}
class Page extends Component {
constructor(props) {
super(props);
this.state = {
loading: true,
error: undefined,
user: undefined
};
}
componentDidMount() {
setTimeout(() => {
this.setState({
loading: false,
user: {
options: {
useRoundedImages: "test"
}
}
});
}, 2000);
}
render() {
return (
<LoadWrapper loading={this.state.loading} error={this.state.error}>
<p>{this.state.user?.options.useRoundedImages}</p>
</LoadWrapper>
);
}
}
export default function App() {
return (
<div className="App">
<h1>Hello CodeSandbox</h1>
<h2>Start editing to see some magic happen!</h2>
<Page />
</div>
);
}
这是演示:https ://codesandbox.io/s/thirsty-water-mgwp2?file=/src/App.js:0-1078
推荐阅读
- jquery - 如何汇总动态表格输入表单的所有价格并在新输入类型中附加值?
- ios - Frame SwiftUI内的居中路径形状
- delphi - 程序加载期间添加的菜单项的 Vcl 样式问题
- unity3d - 如何在地图上拖动鼠标进行导航?
- flutter - Firestore 如何在 Flutter 中设置 serverTimestamp 行为?
- pyspark - 将数据从一个表加载到配置单元中的另一个表
- python - 使用过滤器标准在python中分组
- javascript - 我如何使用 chart.js 创建一个同时具有一条时间序列线和一条线性线的图表?
- microsoft-teams - 自定义选项卡的深层链接 - thread.skype vs thread.tacv2
- c# - 如何订阅活动