即使在状态更改后组件也不会更新

时间:2021-05-04 07:19:57

标签: javascript reactjs react-hooks components rendering

我有这个朋友组件,我在数据库中搜索用户的朋友(存储在用逗号分隔的字符串中)并将它们显示在可滚动的 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;

1 个答案:

答案 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);
    }