Home > Back-end >  React SetState array not updating
React SetState array not updating

Time:02-21

I have a Google map in my react application which allows users to sign up (by entering their name). It then gets their location every 1 second and sends it to all the other users currently using the app.

I am trying to plot the users on a map using google-map-react. This should update every time a user is added, or their location changes and reflect this with their marker moving on the map.

It is console logging the usersArray correctly, but users is not being updated, am I doing setState wrong?

const Map = ({ location, zoomLevel }) => {
    const { name } = useParams();
    const [messages, setMessages] = useState([]);
    const ws = useRef();
    let [latitude, setLatitude] = useState('');
    let [longitude, setLongitude] = useState('');
    const [isConnectionOpen, setConnectionOpen] = useState(false);
    const [users, setUsers] = useState([]);

    useEffect(() => {
        ws.current = new WebSocket('ws://localhost:8081');
        //new user has connected
        ws.current.onopen = () => {
            setConnectionOpen(true);
        };
        //sending message to other users
        ws.current.onmessage = (ev) => {
            const message = JSON.parse(ev.data);
            //update users function
            handleAddNewUser(message);
            setMessages((_messages) => [..._messages, message]);
        };
        return () => {};
    }, []);

    //checks if a message has been received my a new user. If existing user - update location
    function handleAddNewUser(message) {
        let usersArray = [];
        let newUser = true;
        if (users.length == 0) {
            usersArray.push(message);
        } else {
            for (let user of users) {
                if (message.sender == user.sender) {
                    newUser = false;
                    user = message;
                }
            }
            if (newUser == true) {
                usersArray.push(message);
            }
        }
        console.log(usersArray);
        // update the state to the updatedUsers
        setUsers(usersArray);
        console.log(users);
    } 

    //triggers the send function every 1 second
    useEffect(() => {
        const interval = setInterval(() => {
            send();
        }, 1000);
        return () => clearInterval(interval);
    }, []);

    //sends the users location as a message to all the other users
    const send = () => {
        if (navigator.geolocation) {
            navigator.geolocation.watchPosition(function (position) {
                latitude = position.coords.latitude.toString();
                longitude = position.coords.longitude.toString();
                ws.current.send(JSON.stringify({ sender: name, latitude: latitude, longitude: longitude }));
                setLatitude('');
                setLongitude('');
            });
        }
    };

    return (
        <div className='map'>
            <div className='google-map'>
                <GoogleMapReact
                    bootstrapURLKeys={{ key: 'keyID' }}
                    defaultCenter={location}
                    defaultZoom={zoomLevel}>
                     users.map(user => {
                    <MyGreatPlace lat={user.latitude} 
                    lng={user.longitude} text=  
                    {user.sender} />
                 })
                </GoogleMapReact>
            </div>
        </div>
    );
};
export default Map;

Also, when plotting the users on the map, i am getting this error: Unexpected token. Did you mean {'>'} or >?

CodePudding user response:

You should check if user exist first. Like this:

if(users){ setUsers(userArray) }

CodePudding user response:

Try logging users in useEffect with users in the dependency array.

//triggers the send function every 1 second
useEffect(() => {
    console.log(users)
    const interval = setInterval(() => {
        send();
    }, 1000);
    return () => clearInterval(interval);
}, [users]);

And to render map you usually do it like that:

{
    users.map((user, i) => <li>user</li>)
}
  • Related