-1

I have a simple React component and inside of it I am fetching data from a remote API, and I want to console.log it in useEffect. I am trying to do it but nothing doesn't get logged into the console, why? What am I missing here? Here is the component:

import React, { useState, useEffect } from 'react';

import { useLocalization } from '@progress/kendo-react-intl';
import { Card, CardHeader, Avatar, CardTitle, CardSubtitle } from '@progress/kendo-react-layout';
import { guid } from '@progress/kendo-react-common';

import { Scheduler } from './../components/Scheduler';

import { employees } from './../resources/employees';
import { images } from './../resources/images';
import { orders, ordersModelFields } from './../resources/orders';
import { teams } from './../resources/teams';

// const orderEmployees = employees.filter(employee => employee.jobTitle === 'Sales Representative');
// const initialFilterState = { };

// orderEmployees.forEach(employee => {
//     if(employee.fullName === 'Wait Peperell') {
//         initialFilterState[employee.id] = false;
//     } else {
//         initialFilterState[employee.id] = true;
//     }
// });

const Planning = () => {
    const localizationService = useLocalization();
    const [filterState, setFilterState] = React.useState(initialFilterState);
    const [data, setData] = React.useState(orders);
    const [fetchedData, setFetchedData] = React.useState(null);


     
    useEffect(() => {
        fetch("https://mocki.io/v1/29b83c0b-1a55-430d-a173-92b3632e04aa")
        .then(response => response.json())
            // 4. Setting *dogImage* to the image url that we received from the response above
        .then(data => setFetchedData(data))
        console.log(fetchedData)
      },[])
   
    //   console.log(fetchedData)


    const onDataChange = React.useCallback(
        ({ created, updated, deleted }) => {
            setData(old => old
                // Filter the deleted items
                .filter((item) => deleted.find(current => current[ordersModelFields.id] === item[ordersModelFields.id]) === undefined)
                // Find and replace the updated items
                .map((item) => updated.find(current => current[ordersModelFields.id] === item[ordersModelFields.id]) || item)
                // Add the newly created items and assign an `id`.
                .concat(created.map((item) => Object.assign({}, item, { [ordersModelFields.id]: guid() }))))
        },
        []
    );

    const onEmployeeClick = React.useCallback(
        (employeeId) => {
            setFilterState({
                ...filterState,
                [employeeId]: !filterState[employeeId]
            });
        },
        [filterState, setFilterState]
    );

    return (
        <div id="Planning" className="planning-page main-content">
            <div className="card-container grid">
                <h3 className="card-title">{localizationService.toLanguageString('custom.teamCalendar')}</h3>
                {

                    orderEmployees.map(employee => {
                        return (
                            <div
                                key={employee.id}
                                onClick={() => onEmployeeClick(employee.id)}
                                style={!filterState[employee.id] ? {opacity: .5} : {}}
                            >
                                <Card style={{ borderWidth: 0, cursor: 'pointer'}}>
                                    <CardHeader className="k-hbox" >
                                        <Avatar type='image' shape='circle' size={'large'} style={{
                                            borderWidth: 2,
                                            borderColor: teams.find(({teamID}) => teamID === employee.teamId).teamColor,
                                        }}>
                                            <div className="k-avatar-image" style={{
                                                backgroundImage: images[employee.imgId + employee.gender],
                                                backgroundSize: 'cover',
                                                backgroundPosition: 'center center',
                                            }}
                                            />
                                        </Avatar>
                                        <div>
                                            <CardTitle style={{color: teams.find(({teamID}) => teamID === employee.teamId).teamColor}}>{employee.fullName}</CardTitle>
                                            <CardSubtitle>{employee.jobTitle}</CardSubtitle>
                                        </div>
                                    </CardHeader>
                                </Card>
                            </div>
                        );
                    })
                }
                <div className="card-component" >
                    <Scheduler
                        data={data.filter(event => filterState[event.employeeID])}
                        onDataChange={onDataChange}
                        modelFields={ordersModelFields}
                        resources={[
                            {
                                name: 'Teams',
                                data: teams,
                                field: 'teamID',
                                valueField: 'teamID',
                                textField: 'teamName',
                                colorField: 'teamColor'
                            }
                        ]}
                    />
                </div>
            </div>
        </div>
    );
}

export default Planning;



I also tried to place the console.log outside of useEffect but still, nothing gets console.logged.

Phat Baba
  • 53
  • 7
  • Does this answer your question? [useState set method not reflecting change immediately](https://stackoverflow.com/questions/54069253/usestate-set-method-not-reflecting-change-immediately) **And** this? [How to return the response from an asynchronous call](https://stackoverflow.com/questions/14220321/how-to-return-the-response-from-an-asynchronous-call) – David Dec 22 '21 at 20:39
  • No, didn't answer it – Phat Baba Dec 22 '21 at 20:42
  • Sure it does. Look in the function you pass to `useEffect`. There are two mistakes being made there. (1) You're trying to read the result of the AJAX operation before that operation completes (see second linked duplicate). (2) You're trying to read the updated state immediately after updating it (see first linked duplicate). Move the `console.log` operation into the second `.then()` function and log `data` to the console instead of `fetchedData`. – David Dec 22 '21 at 20:45

2 Answers2

3

You need to look how useEffect work, setFetchedData is async.

Create another useEffect only for console.log.

    useEffect(() => {
        console.log(fetchedData);
      },[fetchedData]); // Update at the first render + when fetchedData state change.
Muhammad Dyas Yaskur
  • 6,914
  • 10
  • 48
  • 73
mkreber
  • 31
  • 1
2

You can do it like this

useEffect(() => {
  fetch("https://mocki.io/v1/29b83c0b-1a55-430d-a173-92b3632e04aa")
    .then((response) => response.json())
    // 4. Setting *dogImage* to the image url that we received from the response above
    .then((data) => {
      setFetchedData(data);
      console.log(data);
    });
}, []);

or juste create another useEffect that listens to fetchedData change, like this

useEffect(() => {
  console.log(fetchedData);
}, [fetchedData]);
Lahcen
  • 1,231
  • 11
  • 15