gpt4 book ai didi

javascript - React - componentWillMount() 中的 setState 导致 UI 滞后

转载 作者:行者123 更新时间:2023-12-01 02:46:58 27 4
gpt4 key购买 nike

我必须在 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 请求方法(如 componentWillMountconstructor )不是上面提到的最佳实践,所以这就是为什么我们在 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/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com