- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我必须在 componentWillMount()
中获取一些数据,这需要一些时间(2 秒),在此之后,我使用 setState
来更新状态中的一些值,由于此 setState
重新呈现 UI,因此组件初始呈现和 setState 呈现之间存在延迟,有什么方法可以解决此 UI 延迟?
更新:如果我想使用加载指示器,我应该把它放在哪里?我使用 promise 来获取我的数据,如下所示:
componentDidMount() {
api.getData().then((response) => { ... }
最佳答案
你不应该在 componentWillMount
中使用异步操作或 constructor
.
而是在 componentDidMount
中进行.
您可以在 DOCS 中阅读相关信息
setting state synchronously in this method will not trigger a re-rendering. Avoid introducing any side-effects or subscriptions in this method.
编辑
作为您更新问题的后续行动
if I want to use a loading indicator, where should I put it? I use a promise to fetch my data
我做了一个获取数据并在获取数据时渲染加载程序的小示例。
在这个例子中,我使用了一个名为 jsonplaceholder 的免费 API 测试器。 ,我正在使用这个 URL获取用户的一些随机数据。
你可以看到我在 contructor
中初始化状态 为空数组 users
,我正在获取用户在componentDidMount
生命周期方法和更新users
已返回的 promise 回调中的状态数组。请注意,我是在 setTimeOut
中做的方法以获得2秒的延迟。
现在,React 不会真正等待我们的 ajax 请求返回结果,它会调用 render
方法无论如何,因此在 render
之前运行的生命周期方法中执行 ajax 请求方法(如 componentWillMount
或 constructor
)不是上面提到的最佳实践,所以这就是为什么我们在 componentDidMount
中执行它方法。
您可能会问,那么好吧!但是,我应该如何在接收到数据之前 渲染什么,然后在接收到数据之后 渲染数据?很高兴你问到:)
我们可以使用 React 的生命周期为我们工作,并利用强大的渲染选项和状态更新。
在这个例子中,我有条件地渲染了一个 <Loader />
或数据 <UserList/>
在 ternary operator 的帮助下.
return ({this.state.users.length > 0 ? <UserList /> : <Loader/>);
这样,每当 users
状态数组为空,它将呈现 Loader
组件,状态将更新后(这将在 ajax 请求完成后发生)render
方法将再次调用,但这次条件将返回 true
因此 UserList
将呈现但不 Loader
.
下面是完整的运行示例:
const apiUrl = "https://jsonplaceholder.typicode.com/users";
const User = ({ name, username, email }) => (
<div style={{ border: "1px solid #ccc", padding: "15px" }}>
<div>Name: {name}</div>
<div>User Name: {username}</div>
<div>E-Mail: {email}</div>
</div>
);
const UserList = ({ users }) =>(
<div>
{users.map(user => <User key={user.id} {...user} />)}
</div>
);
const Loader = () => (
<div id="escapingBallG">
<div id="escapingBall_1" className="escapingBallG"></div>
</div>
);
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
users: []
};
}
componentDidMount() {
// mimic 2 seconds delay
setTimeout(() => {
axios.get(apiUrl)
.then(users => {
this.setState({
users: [...users.data]
});
})
.catch(err => console.log(err));
}, 2000);
}
render() {
const { users } = this.state;
return (
<div>
{
users.length > 0 ? <UserList users={users} /> : <Loader />
}
</div>
);
}
}
ReactDOM.render(<App />, document.getElementById("root"));
#escapingBallG{
position:relative;
width:125px;
height:43px;
margin:auto;
}
.escapingBallG{
background-color:rgb(0,0,0);
position:absolute;
top:0;
left:0;
width:43px;
height:43px;
border-radius:21px;
-o-border-radius:21px;
-ms-border-radius:21px;
-webkit-border-radius:21px;
-moz-border-radius:21px;
animation-name:bounce_escapingBallG;
-o-animation-name:bounce_escapingBallG;
-ms-animation-name:bounce_escapingBallG;
-webkit-animation-name:bounce_escapingBallG;
-moz-animation-name:bounce_escapingBallG;
animation-duration:1.5s;
-o-animation-duration:1.5s;
-ms-animation-duration:1.5s;
-webkit-animation-duration:1.5s;
-moz-animation-duration:1.5s;
animation-iteration-count:infinite;
-o-animation-iteration-count:infinite;
-ms-animation-iteration-count:infinite;
-webkit-animation-iteration-count:infinite;
-moz-animation-iteration-count:infinite;
animation-timing-function:linear;
-o-animation-timing-function:linear;
-ms-animation-timing-function:linear;
-webkit-animation-timing-function:linear;
-moz-animation-timing-function:linear;
animation-delay:0s;
-o-animation-delay:0s;
-ms-animation-delay:0s;
-webkit-animation-delay:0s;
-moz-animation-delay:0s;
transform:scale(0.5, 1);
-o-transform:scale(0.5, 1);
-ms-transform:scale(0.5, 1);
-webkit-transform:scale(0.5, 1);
-moz-transform:scale(0.5, 1);
}
@keyframes bounce_escapingBallG{
0%{
left:0px;
transform:scale(0.5, 1);
}
25%{
left:41px;
transform:scale(1, 0.5);
}
50%{
left:103px;
transform:scale(0.5, 1);
}
75%{
left:41px;
transform:scale(1, 0.5);
}
100%{
left:0px;
transform:scale(0.5, 1);
}
}
@-o-keyframes bounce_escapingBallG{
0%{
left:0px;
-o-transform:scale(0.5, 1);
}
25%{
left:41px;
-o-transform:scale(1, 0.5);
}
50%{
left:103px;
-o-transform:scale(0.5, 1);
}
75%{
left:41px;
-o-transform:scale(1, 0.5);
}
100%{
left:0px;
-o-transform:scale(0.5, 1);
}
}
@-ms-keyframes bounce_escapingBallG{
0%{
left:0px;
-ms-transform:scale(0.5, 1);
}
25%{
left:41px;
-ms-transform:scale(1, 0.5);
}
50%{
left:103px;
-ms-transform:scale(0.5, 1);
}
75%{
left:41px;
-ms-transform:scale(1, 0.5);
}
100%{
left:0px;
-ms-transform:scale(0.5, 1);
}
}
@-webkit-keyframes bounce_escapingBallG{
0%{
left:0px;
-webkit-transform:scale(0.5, 1);
}
25%{
left:41px;
-webkit-transform:scale(1, 0.5);
}
50%{
left:103px;
-webkit-transform:scale(0.5, 1);
}
75%{
left:41px;
-webkit-transform:scale(1, 0.5);
}
100%{
left:0px;
-webkit-transform:scale(0.5, 1);
}
}
@-moz-keyframes bounce_escapingBallG{
0%{
left:0px;
-moz-transform:scale(0.5, 1);
}
25%{
left:41px;
-moz-transform:scale(1, 0.5);
}
50%{
left:103px;
-moz-transform:scale(0.5, 1);
}
75%{
left:41px;
-moz-transform:scale(1, 0.5);
}
100%{
left:0px;
-moz-transform:scale(0.5, 1);
}
}
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="root"></div>
关于javascript - React - componentWillMount() 中的 setState 导致 UI 滞后,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46411168/
我有一个简单的应用程序,它读取数据库,然后经过一些操作将结果写入另一个数据库。 第一行代码使用给用户的消息和屏幕日志更新 ui,然后全部包装在带有 using 和其他 try/catch 的 try/
我有一个名为activity的表,其中有一个memberId和一个时间戳。我想找出在给定的月份中有多少成员执行了一项 Activity (即-在 Activity 表中有记录),但在过去12个月中,谁
我有前三列数据。第一个列表示 id 在前一天做了某件事。我试图通过添加一个新变量“new”来从 dat 转到 dat2,该变量执行三件事: 将 yest 的值复制到前一天。但日子并不总是连续的。因此,
我有一个简单的应用程序,它读取数据库,然后经过一些操作将结果写入另一个数据库。 第一行代码使用给用户的消息和屏幕日志更新 ui,然后全部包装在带有 using 和其他 try/catch 的 try/
我有 data.frame,它显示了股票的当前出价和要价以及我当时的信号。 time bid_price ask_price signal 10:10:01.000500
我无法让网站正常运行。它有许多移动背景并使用 css-invert 过滤器。 请看这里: http://epicstudios.de/blackwhite/ 我的问题是,即使是普通计算机也无法处理移动
我创建了一个矩形对象网格并将它们添加到一个 Pane 中。每个矩形都有一个连接到它的鼠标事件监听器,它由 MouseEvent.Entered 触发器触发。当用户将鼠标移到矩形上时,处理程序只是更改矩
感觉我的笔记本电脑不允许控制台应用程序以一定的速度运行,因为我也尝试过其他应用程序,并且它们也随机滞后。我的机器不老,也不应该这样做,它具有i7-4720HQ CPU @ 2.60GHz(8 CPUs
我现在正面临这个问题。当我的页面加载 (DOM) 时,我调用一个返回 1880 张图像的函数,这些图像存储在 Steam 服务器中。 这些图像在回调之后被添加到我的 DOM 中,该回调返回我的数组响应
我正在尝试创建一个每两秒执行一次函数的应用程序。为了实现这一点,我使用 Timer.scheduledTimer 函数。问题是该函数没有按照应有的那样每两秒执行一次。通常应用程序开始时的间隔是 2 秒
我得到了这个 gps 接收器方法,它将一些数据存储到数据库中。 // GPS private void addGPSListener() { globalconstant.db
我有一个 UISwitch,它可以在切换值时更改其上方 UILabel 的文本。每隔一段时间(大约 2% 的时间)文本不会改变。标签的文本被保存到文本文件中,因此我需要准确性。由于这个问题是间歇性的,
我有一个包含用户帖子的表格 View 。每个帖子都有图片、用户名和帖子本身。刷新控件的操作是使用来自 Parse 的数据重新加载表。除了拉动刷新时的极度延迟外,一切都完美无缺。不知道是因为每个单元格里
我有一个“详细信息”页面,其中显示俱乐部的信息。该页面是一个 UIViewController,由按钮和标签组成,以实现这种外观(就像分组的小表格)。当我在设备上加载此页面时,它比我的应用程序中的任何
我有 ActionSheet 的代码,它可以连接的东西有点慢? @IBAction func showAction(_ sender: UIButton) { let actionSheetC
我的桌面应用程序滞后。我认为 java.awt.image.BufferStrategy 中有问题。 private void render() { BufferStrategy bs
你好,我有一个包含多个页面的 viewpager(使用 fragment 状态寻呼机),以及一些 png 作为这些页面的背景。我已经遵循了在 Ui 中显示位图 (http://developer.an
我在 WPF 窗体上有一个 richtextbox 控件。它有 SpellChecking.IsEnabled 设置为 true 并且 VerticalScrollBarVisibility 设置为
在我的 android 应用程序中,我将数据存储在本地 SQLite 数据库中。在这个数据库的大小小于 8-9 MB 之前,一切都很顺利;然而,一旦数据库大小约为 9 MB,它就会继续在 logcat
我正在开发一个简单的 Android 应用程序,它只有一个 Activity ,一个 WebView。它在我的手机(Android 7.1.2 Nougat 版本)上运行良好,但我收到许多用户的投诉,
我是一名优秀的程序员,十分优秀!