我有这个朋友组件,我在数据库中搜索用户的朋友(存储在用逗号分隔的字符串中)并将它们显示在可滚动的 div 中。您还可以添加新朋友。数据库和后端一切正常。然而,当状态改变时组件不会被重新渲染。它依赖于“allFriends”,所以它应该在更新时重新渲染。你们知道这里发生了什么吗?我猜它与异步性有关,但我似乎无法确定它。我为每个代码块添加了注释,以使其更易于阅读。
import React, { useState, useEffect } from 'react';
import SingleFriend from './SingleFriend';
import './friends.css';
const Friends = ({username}) => {
const [allFriends, setAllFriends] = useState([]);
const [unsortedFriends, setUnsortedFriends] = useState([]);
const [friendFilter, setFriendFilter] = useState('');
const [friendSearch, setFriendSearch] = useState('');
//-----------------------------------------------------------------------------------
// Start fetching friends on component mount
//-----------------------------------------------------------------------------------
useEffect(() => {
fetchFriends();
}, [])
//-----------------------------------------------------------------------------------
// Sort the friends when fetching has finished/unsortedFriends has updated
//-----------------------------------------------------------------------------------
useEffect(() => {
const onlineFriends = [];
const offlineFriends = [];
unsortedFriends.forEach(f => {
if (f.status === 'online') {
onlineFriends.push(f)
} else {
offlineFriends.push(f)
}
})
setAllFriends(onlineFriends.concat(offlineFriends));
},[unsortedFriends])
//-----------------------------------------------------------------------------------
// Get the string of friends that is stored in the database for the user
// Convert to array of friends
// Pass the array to 'fetchFriendData()'
//-----------------------------------------------------------------------------------
const fetchFriends = () => {
let allFriendNames = [];
fetch(`http://localhost:8000/getFriends?username=${username}`)
.then(res => res.json())
.then(friends => {
if (friends !== null && friends !== '') {
allFriendNames = friends.split(',');
fetchFriendData(allFriendNames);
}
})
}
//-----------------------------------------------------------------------------------
// Search the database for each of the user's friends
// Return those users, and add their username & online status to a temporary array
// Assign that array to the unsortedFriends useState hook
//-----------------------------------------------------------------------------------
const fetchFriendData = (allFriendNames) => {
let allF = [];
for (let friend of allFriendNames) {
fetch(`http://localhost:8000/findFriend?username=${friend}`)
.then(res => res.json())
.then(user => {
if (user.socketid) {
allF.push({name: user.username, status: 'online'})
} else {
allF.push({name: user.username, status: 'offline'})
}
})
.catch(err => console.log(err))
}
document.querySelector('.addFriendInput').value = '';
setUnsortedFriends(allF);
}
//-----------------------------------------------------------------------------------
// Called on button press to add friend
//-----------------------------------------------------------------------------------
const addFriend = () => {
let friendList = '';
let friendArray = [];
//-----------------------------------------------------------------------------------
// Search the database to check if the name that was
// entered matches any users in the databse
//-----------------------------------------------------------------------------------
fetch(`http://localhost:8000/findFriend?username=${friendSearch}`)
.then(res => res.json())
.then(user => {
if (user.username) {
//-----------------------------------------------------------------------------------
// If friend exists, grab the user's friend list string
// Make a temporary string and array with the new friend
//-----------------------------------------------------------------------------------
fetch(`http://localhost:8000/getFriends?username=${username}`)
.then(res => res.json())
.then(friends => {
if (friends !== null && friends !== '') {
friendArray = friends.split(',');
if (friendArray.includes(friendSearch)) {
throw new Error('Problem getting friend')
} else {
friendArray.push(friendSearch);
friendList = friends.concat(`,${friendSearch}`);
}
} else {
friendList = friendSearch;
friendArray = [friends];
}
//-----------------------------------------------------------------------------------
// Update the user's friend list with the new friends string
// Pass the updated friends array to 'fetchFriendData'
//-----------------------------------------------------------------------------------
fetch('http://localhost:8000/addFriend', {
method: 'put',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify({
username: username,
friendlist: friendList
})
})
.then(fetchFriendData(friendArray))
.catch(err => console.log(err))
})
.catch(err => console.log(err))
}
})
.catch(err => console.log(err))
}
return (
<div className='friendsContainer'>
<div className='friendsSection'>
<h2>Friends</h2>
<input onChange={(e) => setFriendFilter(e.target.value)} type='text' placeholder='Enter a username'/>
<div className='friendsListContainer'>
{
allFriends.length
?
<div className='friendsList'>
{
//-----------------------------------------------------------------------------------
// Map through the user's friends
// Return a single friend div w/ their username and status
//-----------------------------------------------------------------------------------
allFriends.map(f => {
if (f.name.toLowerCase().includes(friendFilter.toLowerCase())) {
return <SingleFriend key={f.name} name={f.name} status={f.status}/>
} else return null
})
}
</div>
: <h4 className='noFriends'>No friends have been added</h4>
}
</div>
<div className='addFriend'>
<h3 className='addFriendText' >Add a friend</h3>
<input className='addFriendInput' onChange={(e) => setFriendSearch(e.target.value)} type='text' placeholder='Enter a username'/>
<button onClick={addFriend} >Add</button>
</div>
</div>
</div>
)
}
export default Friends;
答案 0 :(得分:0)
您需要等待获取响应数据
const fetchFriendData = async (allFriendNames) => {
let allF = [];
for (let friend of allFriendNames) {
const response = await fetch(`http://localhost:8000/findFriend?username=${friend}`)
const user = await response.json()
if (user.socketid) {
allF.push({name: user.username, status: 'online'})
} else {
allF.push({name: user.username, status: 'offline'})
}
}
document.querySelector('.addFriendInput').value = '';
setUnsortedFriends(allF);
}