0

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.

1 Answer 1

0

Can you please refactor your useEffect and write it like that?

useEffect(() =>{
  setUpdatedList(usersScoreList)
  }, [usersScoreList])

I think the way you do it without curly braces it returns as a cleanup

Sign up to request clarification or add additional context in comments.

1 Comment

Well, the console.log with array is now rendered more often, but this didn not changed the index and currentPosition. Again, only after refresh. The rest obcjects are normally rerended at once. Strange.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.