I'm using street views from Mapillary.js and depending on an image key, passed as a prop, I want to show different images/street views. I've tried to do it with a conditional (ternary) operator like this:
<Mapillary width="auto" height="94vh" imageId={currentClue === 0 ? '2978574139073965' : currentClue === 1 ? '461631028397375' : currentClue === 2 ? '2978574139073965' : currentClue === 3 ? '312627450377787' : currentClue === 4 ? '695710578427767' : ''} />
Right now though, I only see the first image (when currentClue === 0). When currentClue === 1, the first image is still showing, although I can see in the console that the currentClue index is ascending.
I've also tried to change image by saving imageId in state and using it like this:
const handleClick = () => {
setCurrentClue(currentClue + 1);
if (currentClue < 4) { //* Show alert if clue index > 4
setLevel(level - 1);
if (currentClue === 1) setImageId('461631028397375')
if (currentClue === 2) setImageId('2978574139073965')
} else {
swal('Time to make a guess!', {
button: 'OK'
});
}
dispatch(game.actions.setScore(currentScore - 1));
};
This is the whole component where I'm trying to do this:
import React, { useState, useEffect } from 'react';
import { useDispatch, useSelector } from 'react-redux';
import { game } from 'reducers/game';
import swal from 'sweetalert';
import { Mapillary } from 'components/Mapillary/Mapillary';
import { Paragraph } from 'GlobalStyles';
import { MapillaryContainer, ClueContainer, SpecialSpan, ClueParagraph, AnotherClueButton } from './Clues.Styles'
export const Clues = () => {
const [games, setGames] = useState([])
const [loading, setLoading] = useState(false);
const [currentClue, setCurrentClue] = useState(0);
const [level, setLevel] = useState(5);
// const [imageId, setImageId] = useState('2978574139073965')
//* Fetching clues
const fetchClues = () => {
setLoading(true);
fetch('https://final-project-api-veooltntuq-lz.a.run.app/games')
.then((response) => {
return response.json()
})
.then((response) => {
setGames(response.games)
})
.catch((error) => console.error(error))
.finally(() => setLoading(false));
}
//* Setting current score
const currentScore = useSelector((store) => store.game.score);
const dispatch = useDispatch();
const handleClick = () => {
setCurrentClue(currentClue + 1);
if (currentClue < 4) { //* Show alert if clue index > 4
setLevel(level - 1);
/* if (currentClue === 1) setImageId('461631028397375')
if (currentClue === 2) setImageId('2978574139073965') */
} else {
swal('Time to make a guess!', {
button: 'OK'
});
}
dispatch(game.actions.setScore(currentScore - 1));
};
useEffect(() => {
fetchClues()
}, [])
const activeClue = games[currentClue];
if (loading) {
return <Paragraph>Loading clues...</Paragraph>
}
if (currentClue < 5) { //* Stop showing clues after clue 5
return (
<div>
<MapillaryContainer>
{console.log(currentClue)}
<Mapillary width="auto" height="94vh" imageId={currentClue === 0 ? '2978574139073965' : currentClue === 1 ? '461631028397375' : currentClue === 2 ? '2978574139073965' : currentClue === 3 ? '312627450377787' : currentClue === 4 ? '695710578427767' : ''} />
</MapillaryContainer>
<ClueContainer>
<SpecialSpan>Level: {level}</SpecialSpan>
<ClueParagraph>{activeClue && activeClue.gameOne}</ClueParagraph>
<AnotherClueButton type="button" onClick={() => handleClick()}>I need another clue</AnotherClueButton>
</ClueContainer>
</div>
)
}
}
Mapillary
component does. Perhaps it is only using the imageId
at load time, and after then ignores changes to it. Does it work if you add key={currentClue}
? Although this might be bad for performance depending on what that component does, and how often the currentClue
changes. I think your second method will be work, the error is that you are adding and checking the currentClue
value in the same function, your state is not updated, you have to use useEffect it will detect the change of currentClue
state and change the image according to your state value, I hope it works.
here is one more thing you just need to handle the dispatch
according to your requirements because useEffect
will be called once your component load.
const handleClick = () => {
const val = currentClue + 1;
setCurrentClue(val);
};
useEffect(() => {
if (currentClue < 4) { //* Show alert if clue index > 4
setLevel(level - 1);
if (currentClue === 1) setImageId('461631028397375')
if (currentClue === 2) setImageId('2978574139073965')
} else {
swal('Time to make a guess!', {
button: 'OK'
});
}
dispatch(game.actions.setScore(currentScore - 1));
}, [currentClue])