0

Edit: Please find my whole component code down below. No "data" state refreshed on useEffect ... What's the heck !!!

I get data from firebase in useEffect. In useEffect, I store my data( which is an array) in a state using useState. I want to use this data in my rfc render method but first need to reduce() it. I tried to reduce it in original useEffect (the same where I am fetching the data), in a other useEffect, or even in my render method. None of these could actually make it. My accumulator argument stays empty in my reduce function. Please, I really need some help on this.


 import React, { useState, useEffect } from 'react'
import { Grid, Paper, Typography, Table, TableBody, TableCell, TableHead, TableRow } from '@material-ui/core'
import firebase from './../firebase'

const db = firebase.firestore()

export default function Scores(props) {

    let { match } = props
    let [currentEvent, setcurrentEvent] = useState(null)
    let [records, setRecords] = useState([])
    let [data, setdata] = useState(null)




    useEffect(() => {
        console.log("effet 1")
        db.collection('events').doc(match.params.id)
          .onSnapshot(doc => {

            setcurrentEvent(currentEvent = { ...doc.data(), uid: doc.id })
            setRecords(records = doc.data().records)
          })

      }, [])

      useEffect(() => {
            console.log(records)
          let x = records.reduce((result, record) => {
              console.log(record)
            result[record.user] = result[record.user] || []
            result[record.user].push(record.time.seconds)
            console.log(result)
            return result
        }, [])
          console.log(x)
          setdata(data = x)

      }, [records])






      if (!currentEvent) {
          return (<h1>data loading ...</h1>)
      }

      return (
          <Paper style={{margin: 8, padding: 8}}>
              <Typography variant='h4'>
                {data.length}
              </Typography>

              <Typography>

              </Typography>


              <Table >
                <TableHead>
                    <TableRow>
                        <TableCell>Participant</TableCell>
                        <TableCell align="right">run 1</TableCell>
                        <TableCell align="right">run 2</TableCell>
                        <TableCell align="right">run 3</TableCell>

                    </TableRow>
                </TableHead>
                <TableBody>


                </TableBody>
            </Table>

          </Paper>
      )




}



/*
useEffect(() => {
          console.log("hi")
          console.log(records)
        let data = records.reduce((result, record) => {
            result[record.user] = result[record.user] || []
            result[record.user].push(record.time.seconds)
            console.log('coucou')
            return result
        }, [])
        setRecords(records = 'coucou')
      }, [])

*/

2 Answers 2

1

It looks like you're handling everything inside of a return function, with useEffect that works similar to a componentWillUnmount - as explained in the docs

Try to run your reduce logic before the return function:

useEffect(() => {
    let records = [];
    let x = records.reduce((result, record) => {
      result[record.user] = result[record.user] || []
      result[record.user].push(record.time.seconds)
      return result
  }, [])
  setdata(data = x)
  }, [records])
Sign up to request clarification or add additional context in comments.

5 Comments

Hum... If you start 'records' being an empty array, How do you want it to do anything ? I think the return function as nothing to do with that...
I think that my manipulation over the array is right. The problem is about the state not updating. And I don't know why. I can setdata to a simple variable and it works good, but as soon as I use reduce(), something strange is happening....
I think no render method is call afterwards. But useState is called in useEffect, so render should fire !!!
We're talking about the wrong return function, the return you are calling at the top of useEffect is making it so your useEffect does nothing when it mounts
All of your logic is only being called on unmount
1
setdata(data = x)

This is not how you should be using the useState hook. In this line you're trying to assign a value to your state variable as an argument to your state update function.

It should look like this setdata(x)

More info here ...

Check your dev tools for errors (TypeError: Assignment to constant variable.).

Comments

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.