我正在 React 中開發一個 Top10UserList 組件,它從 api 獲取前 10 個用戶,然后為每個用戶獲取影像并成功地為每個用戶創建一個影像標簽,并且應該在他們自己的標簽中顯示每個用戶的影像。
不幸的是,每個影像都共享相同的狀態,因此它們都快速閃過所有 10 個影像,然后停留在最終影像上。
我需要它們分開,但我不確定如何重構我的代碼來實作這一點。
反應組件:
const TOP_USERS_URL = 'http://localhost:8080/users/top-players'
const TOP_TEN_USERS_URL = 'http://localhost:8080/users/top-10-players'
const TOP_TEN_USERS_IMAGES_URL = 'http://localhost:8080/image-files/download-using-username'
const USER_IMG_URL = 'http://localhost:8080/image-files/'
class TopUserList extends Component {
constructor(props) {
super(props);
this.state = { users: [], top10Users: [], token: '', top10UsersImages: [], profUrl: '', profileImage: '' };
}
componentDidMount() {
fetch(TOP_USERS_URL, {
method: 'GET',
headers: {
"Accept": "application/json",
"Content-Type": "application/json",
"Authorization": localStorage.getItem("token")
},
})
.then(response => response.json())
.then(data => this.setState({ users: data }));
fetch(TOP_TEN_USERS_URL, {
method: 'GET',
headers: {
"Accept": "application/json",
"Content-Type": "application/json",
"Authorization": localStorage.getItem("token")
},
})
.then(response => response.json())
.then(data => {
this.setState({ top10Users: data });
console.log(data);
console.log("Data[0]")
console.log(data[0].username)
data.forEach(element => {
const imgUrl = USER_IMG_URL element.username;
const id = element.id;
fetch(imgUrl, {
method: 'GET',
headers: {
"Authorization": localStorage.getItem("token")
}
})
.then(r => r.arrayBuffer())
.then(buffer => {
const blob = new Blob([buffer]);
this.state.img = URL.createObjectURL(blob);
});
const fetchImage = async (url) => {
try {
const response = await fetch(url, {
headers: {
"Authorization": localStorage.getItem("token")
}
});
const imageBytes = await response.arrayBuffer();
var blob = new Blob([imageBytes], { type: "image/jpeg" });
var imageUrl = URL.createObjectURL(blob);
return imageUrl;
} catch (error) {
console.log("ERROR:", error);
}
};
const profileUrl = "profile-image-" id;
this.state.profUrl = profileUrl;
(async () => {
const imageSrc = await fetchImage(imgUrl);
console.log("ImageSRC:");
console.log(imageSrc);
console.log("Profile Url:");
console.log(profileUrl);
this.setState({ profileImage: imageSrc })
})();
console.log("Profile Url:");
console.log(profileUrl);
document.getElementById("app").innerHTML = `
<image id={profileUrl}>
`;
}
);
});
}
render() {
const { users, top10Users, isLoading, profileUrl, profileImage} = this.state;
console.log("Top 10 users data: ")
console.log(top10Users);
console.log("Top 10 users using index: ");
console.log(top10Users[0]);
console.log("ProfUrl: ");
console.log(profileUrl);
console.log("profImg");
console.log(profileImage);
if (isLoading) {
return <p>Loading...</p>;
}
const topUserList = users.map(user => {
return <tr key={user.id}>
<td style={{ whiteSpace: 'nowrap' }} class="player-list-key-text">{user.name}</td>
<td class="player-list-key-text">{user.username}</td>
<td class="player-list-key-text">{user.location}</td>
</tr>
});
const topTenUserList = top10Users.map(user => {
return <div className="user-container" key={user.id}>
<Card>
<div id="app"></div>
<img src={profileImage} style={{ width: 200, height: 200 }} />
<CardTitle>{user.name}</CardTitle>
</Card>
</div>
})
return (
<div className="outer-div-container">
<div>
<Container fluid>
<h3 className="player-list-header">Top Players</h3>
<Table className="mt-4">
<thead>
<tr id="player-list-row">
<th className="player-list-data-text">Name</th>
<th className="player-list-data-text">Username</th>
<th className="player-list-data-text">Location</th>
</tr>
</thead>
<tbody>
{topUserList}
</tbody>
</Table>
{topTenUserList}
</Container>
</div>
</div>
);
}
}
export default TopUserList;
結果:

我如何在 React 中做到這一點?我需要創建 10 個不同的影像狀態值嗎?
謝謝你的幫助!
更新代碼:
class TopUserList extends Component {
constructor(props) {
super(props);
this.state = { users: [], top10Users: [], token: '', top10UsersImages: [], profUrl: '', profileImage: {} };
}
componentDidMount() {
fetch(TOP_USERS_URL, {
method: 'GET',
headers: {
"Accept": "application/json",
"Content-Type": "application/json",
"Authorization": localStorage.getItem("token")
},
})
.then(response => response.json())
.then(data => this.setState({ users: data }));
fetch(TOP_TEN_USERS_URL, {
method: 'GET',
headers: {
"Accept": "application/json",
"Content-Type": "application/json",
"Authorization": localStorage.getItem("token")
},
})
.then(response => response.json())
.then(data => {
this.setState({ top10Users: data });
console.log(data);
console.log("Data[0]")
console.log(data[0].username)
const profileImagesData = {}
data.forEach((element, userIndex) => {
const imgUrl = USER_IMG_URL element.username;
const id = userIndex;
fetch(imgUrl, {
method: 'GET',
headers: {
"Authorization": localStorage.getItem("token")
}
})
.then(r => r.arrayBuffer())
.then(buffer => {
const blob = new Blob([buffer]);
this.state.img = URL.createObjectURL(blob);
});
const fetchImage = async (url) => {
try {
const response = await fetch(url, {
headers: {
"Authorization": localStorage.getItem("token")
}
});
const imageBytes = await response.arrayBuffer();
var blob = new Blob([imageBytes], { type: "image/jpeg" });
var imageUrl = URL.createObjectURL(blob);
profileImageData[element?.id] = imageSrc
return imageUrl;
} catch (error) {
console.log("ERROR:", error);
}
};
const profileUrl = "profile-image-" id;
this.state.profUrl = profileUrl;
(async () => {
const imageSrc = await fetchImage(imgUrl);
console.log("ImageSRC:");
console.log(imageSrc);
console.log("Profile Url:");
console.log(profileUrl);
this.setState({profileImage:{...profileImageData}})
})();
console.log("Profile Url:");
console.log(profileUrl);
document.getElementById("app").innerHTML = `
<image id={profileUrl}>
`;
}
);
});
}
render() {
const { users, top10Users, isLoading, profileUrl, profileImage} = this.state;
console.log("Top 10 users data: ")
console.log(top10Users);
console.log("Top 10 users using index: ");
console.log(top10Users[0]);
console.log("ProfUrl: ");
console.log(profileUrl);
console.log("profImg");
console.log(profileImage);
if (isLoading) {
return <p>Loading...</p>;
}
const topUserList = users.map(user => {
return <tr key={user.id}>
<td style={{ whiteSpace: 'nowrap' }} class="player-list-key-text">{user.name}</td>
<td class="player-list-key-text">{user.username}</td>
<td class="player-list-key-text">{user.location}</td>
</tr>
});
const topTenUserList = top10Users.map(user => {
return <div className="user-container" key={user.id}>
<Card>
<div id="app"></div>
<img src={this.state.profileImage[user.id]} style={{ width: 200, height: 200 }} />
<CardTitle>{user.name}</CardTitle>
</Card>
</div>
})
return (
<div className="outer-div-container">
<div>
<Container fluid>
<h3 className="player-list-header">Top Players</h3>
<Table className="mt-4">
<thead>
<tr id="player-list-row">
<th className="player-list-data-text">Name</th>
<th className="player-list-data-text">Username</th>
<th className="player-list-data-text">Location</th>
</tr>
</thead>
<tbody>
{topUserList}
</tbody>
</Table>
{topTenUserList}
</Container>
</div>
</div>
);
}
}
export default TopUserList;
uj5u.com熱心網友回復:
您可以通過將您的 profileImage 狀態從字串值轉換為物件來實作,其中該物件的鍵將是您的用戶 ID,值將是影像 url
在您的代碼中,您可能需要進行以下更改
您
profileImage:''在建構式中的狀態變數應替換為profileImage:{}在
componentDidMount初始化const profileImageData = {}此行上方的變數data.forEach(element在下
const imageSrc = await fetchImage(imgUrl);,一旦你得到回應,做profileImageData[element?.id] = imageSrc(我假設你的每個 top10User 陣列都有一個 id 變數)替換
this.setState({ profileImage: imageSrc })為this.setState({profileImage:{...profileImageData})在您的 top10UserList 中,替換
<img src={profileImage} style={{ width: 200, height: 200 }} />為<img src={this.state.profileImage[user.id]} style={{ width: 200, height: 200 }} />如果您沒有 id 值,那么您可以替換
data.forEach(element為data.forEach((element, userIndex)并userIndex用作您的鍵值,而不是element.id在 top10UserList 中執行相同操作
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/407310.html
標籤:
