I have a "weird" problem. I have a code in which after downloading data from backend, I update the states, and simply display information about logged user.
The logic downloads user data from server, updates state, and shows current information.
The problem is - only parts of information changes, like user score, but not his his position (index) from array (index is currentPosition in DOM structure)
It looks like this - logic file:
const [usersScoreList, setUsersScoreList] = useState([])
const [liderScore, setLiderScore] = useState('')
const [idle, setIdle] = useState(true)
const fetchUsersScore = async () => {
setIdle(false)
try {
const { data, error } = await getUsersRank({
page: 1,
limit: 0,
sort: usersSort,
})
if (error) throw error
const scoreData = data?.data
const HighestScore = Math.max(...scoreData.map((user) => user.score))
setUsersScoreList((prevData) => [...prevData, ...scoreData])
setLiderScore(HighestScore)
} catch (err) {
console.error(err)
}
}
useEffect(() => {
const abortController = new AbortController()
idle && fetchUsersScore()
return () => abortController.abort()
}, [idle])
Main file -
const { usersScoreList, liderScore } = useScoreLogic()
const [updatedList, setUpdatedList] = useState(usersScoreList)
useEffect(() => setUpdatedList(usersScoreList), [usersScoreList])
const { user } = useAuth()
const { id } = user || {}
const current = updatedList.map((user) => user._id).indexOf(id) + 1
<ScoreBoard
id={id}
score={user.score}
updatedList={updatedList}
currentPosition={current}
liderScore={liderScore}
/>
and component when information is displayed, ScoreBoard:
const ScoreBoard = ({
updatedList,
id,
liderScore,
score,
currentPosition,
}) => {
const { t } = useTranslation()
return (
<ScoreWrapper>
{updatedList?.map(
(user) =>
user._id === id && (
<div>
<StyledTypography>
{t('Rank Position')}: {currentPosition}
</StyledTypography>
<StyledTypography>
{score} {t('points')}
</StyledTypography>
{user.score === liderScore ? (
<StyledTypography>
{t('Congratulations, you are first!')}
</StyledTypography>
) : (
<StyledTypography>
{t('Score behind leader')}: {liderScore - score}
</StyledTypography>
)}
</div>
)
)}
</ScoreWrapper>
)
}
and when the userScoreList in logic is updated (and thus,updatedList in Main file, by useEffect) everything is re-rendered in ScoreBoard (score, score to leader) but not the current position, which is based on index from updatedList array, (const current in main file).
This is a little bit weird. Why the updatedList and usersScoreList arrays changes, user score changes, but not the user index from array while mapping ? (i checked in console.log, user index is based upon score, and yes, during mounting state, the index in arrays are also changed)
If so, why currentPosition is not re-rendered like user score ? It works only when i refresh the page, THEN the new user index is displayed like other informations.