[英]How to get the data in a fetch before the component get mount?
I am trying to make a fetch from a local server in Node, but my problem is that when I call the render function of the component the array users from the state seems to be empty and therefore does not render the users on the screen as I would like, the weird thing is that the console.log(users)
I have inside the fetch does bring me the data, but when I do it on the render does not bring me anything:我正在尝试从 Node 中的本地服务器获取数据,但我的问题是,当我调用组件的渲染函数时,状态中的数组用户似乎是空的,因此不会像我一样在屏幕上渲染用户想,奇怪的是,我在 fetch 中的
console.log(users)
确实给我带来了数据,但是当我在渲染上这样做时并没有给我带来任何东西:
this is the code so far:这是到目前为止的代码:
import React, { PureComponent } from "react";
import Nav from "./Nav";
import { IState, IProps } from "./Interfaces";
class Home extends PureComponent<IProps, IState> {
constructor(props: IProps) {
super(props);
this.state = {
users: [],
books: []
};
}
getUsers = async () => {
const response = await fetch(`http://localhost:5000/users`, {
headers: {
"Content-Type": "application/json"
}
});
const users = await response.json();
for (let user of users) {
this.state.users.push(user);
}
console.log(this.state.users);
};
getBooks = async (id: number) => {
const token =
"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6MSwidXNlciI6Implc3VzIiwiaXNBZG1pbiI6dHJ1ZSwiaWF0IjoxNTc2NjgzNTkwfQ.1FWmtj-fCsqSza_pwfewIpp3zQ50BxDagRTvrh5x3cU";
const response = await fetch(`http://localhost:5000/bookUser/${id}/books`, {
headers: {
Authorization: `Bearer ${token}`,
"Content-Type": "application/json"
}
});
const books = await response.json();
this.setState({ books });
};
onUserSelection = (id: number) => this.getBooks(id);
componentDidlMount() {
this.getUsers();
}
render() {
const { users } = this.state;
console.log(this.state.users);
return (
<div>
<Nav username={this.props.username} />
<h1>Hello {this.props.username}</h1>
<table>
<tbody>
<tr>
<th>ID</th>
<th>Name</th>
</tr>
{users.map(u => (
<tr
key={u.user_id}
onClick={() => this.onUserSelection(u.user_id)}
>
<td>{u.user_id}</td>
{console.log(u.user_id)}
<td>{u.username}</td>
</tr>
))}
</tbody>
</table>
</div>
);
}
}
export default Home;
As previously mentioned in Sameer's comment, you want to avoid using push when setting state.正如之前在 Sameer 的评论中提到的,您希望在设置状态时避免使用推送。 Doing this will not trigger a re-render.
这样做不会触发重新渲染。
Instead of the this.state.users.push(user)
you're doing, replace that (and the console.log following it) with this:而不是你正在做的
this.state.users.push(user)
,用这个替换它(和它后面的 console.log ):
this.setState(prevState => ({
users: [...prevState.users, user]
}, console.log("updated users", this.state.users)));
A few things different here.这里有些不同。
The first argument in setState takes in a function. setState 中的第一个参数接受一个函数。 There is an argument exposed in that function which is your previous state (prevState).
该函数中公开了一个参数,即您之前的状态 (prevState)。 Using the spread operator you can create a new array with the old users and all the new ones.
使用扩展运算符,您可以使用旧用户和所有新用户创建一个新数组。
Secondly, due to the asynchronous nature of setState, you can't expect to run a console.log() right after a setState function.其次,由于 setState 的异步特性,您不能期望在 setState 函数之后立即运行 console.log() 。 Instead, you can pass a callback function (console.log in this instance) as the second argument to setState & it will be fired when completed.
相反,您可以将回调函数(在本例中为 console.log)作为第二个参数传递给 setState & 它将在完成时触发。
Use setState
to populate users in state使用
setState
在 state 中填充用户
this.setState({
users: users
})
and in render before map, do this并在地图之前渲染,执行此操作
{
users.length>0 &&
users.map(u => ( <tr key={u.user_id} onClick={() => this.onUserSelection(u.user_id)} > <td>{u.user_id}</td> {console.log(u.user_id)} <td>{u.username}</td> </tr> ))
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.