The fetch call is asynchronous. This means it is not guaranteed to be complete before the program enters the next line.

Because of this the blogs array will be empty at the first render. You can add an check in the src CardItem component to only use the value returned from the fetch call when it is available:

<CardItem
  src={blogs.length > 0 ? blogs[0].mainImage : ''}
  ...
/>

An alternative would be to use the fact that blogs is an array and use the map operator to build one or more CardItems.

<ul className='cards-items'>
  {blogs.map(blog => <CardItem
    src={blog.mainImage}
    ...
  />)}
</ul>
Answer from MaartenDev on Stack Overflow
Top answer
1 of 2
4

The fetch call is asynchronous. This means it is not guaranteed to be complete before the program enters the next line.

Because of this the blogs array will be empty at the first render. You can add an check in the src CardItem component to only use the value returned from the fetch call when it is available:

<CardItem
  src={blogs.length > 0 ? blogs[0].mainImage : ''}
  ...
/>

An alternative would be to use the fact that blogs is an array and use the map operator to build one or more CardItems.

<ul className='cards-items'>
  {blogs.map(blog => <CardItem
    src={blog.mainImage}
    ...
  />)}
</ul>
2 of 2
3

I faced the same problem, and here is how I solved it..

First, I created a loading state, and set the initial state to true.

//  const [singlePackage, setPackage] = useState([]);

    const [isLoading, setLoading] = useState(true);

then, in the useEffect hook, I set the state to false like so..

useEffect(() => {
   axios.get(baseURL).then((response) => {
      setPackage(response.data);
    setLoading(false);
  })
}, []);

Then, I used a condition, if the loading state is true, return the spinner else return the component like so...

if (isLoading) {
    return (
      <div  className="loadingContainer">
      <Loader
      type="ThreeDots"
      color="#00b22d"
      height={100}
      width={100}
       //3 secs
    />
    </div>
    )
  } else {

    return (
     // your code here
)}

I am using react-loader-spinner, and just styled the container you can install it using...

npm install react-loader-spinner --save

the style for container ...

.loadingContainer{
  position: fixed;
  top: 50%;
  left:50%;
  transform: translate(-50%,50%);
}
🌐
Reddit
reddit.com › r/nextjs › rerender on refresh when using useeffect
r/nextjs on Reddit: Rerender on refresh when using useEffect
April 3, 2023 -

Hello. Title was hard to put together haha.

So, this is the deal.

I'm making a website that has a header with login and register options. If the user already logged in and the data is stored in the cookies, instead of the login and register options it should display a logout option.

I have the following:

A context for the user auth.

First i had the initialState setted as in the 'SET_INITIAL_VALUES' case. But this gave me hydration issues because the server had no access to the cookies so the final document was different. (tried solving this using getServerSideProps but that gave me another issues).

In order for this to work i had to make the 'SET_INITIAL_VALUES' changes in an useEffects.

This is the Header component.

So, i use the state of userInfo to know if the user logged in previously.

This all works but when i login and then refresh the page, i can see the effect from the rerender. That is, i first see the login and register options but after half a second it changes to the proper logout option. Is there a better way to deal with this and solve this issue?

I'm fairly new to Nextjs.

Top answer
1 of 3
2
What was the issue with using `getServerSideProps` ? You can read the cookies there and the pass props down based on wether the user is logged in (cookies exist) and display the correct option. Otherwise I'd say starting with either: A neutral state where no 'login/register' or 'account' option is shown. Then you wait till you can read the state before displaying the correct option. This would still give you a 'flash' of no options before displaying the correct one. As you are have the default 'login/register' options, then when hydrated & have read the cookies, update to the correct 'account' option or remain as is 'login/register'. To me as both a user & developer isn't a big deal but this is just an opinion. There is another question, just because the user has the cookies existing "do they actually still have a valid login"? What happens if a user has logged in then their account is deleted/banned etc, using option 2 you could once the page is hydrated make a call to validate their login cookie to ensure they can still access the account options. To me seems the most practical even if it gives a brief flash of the 'login/register' option.
2 of 3
1
The only easiest solution that fits into your current patterns I could think of quickly… add another value to your store, let’s call it ‘userInfoFetched’ and set it to false as the default value. In your reducer add ‘userInfoFetched: true’ to all three cases. In your header, first check to see the value of ‘userInfoFetched’. If the value is true you can render the login or register buttons the same as before, if it is false either render nothing, or some button loading state. Now if you want to render everything properly on first paint instead of having the delay, you would instead move the cookie logic to getServerSideProps and pass the data to the header component so everything is able to render server side.
Top answer
1 of 2
3

You might want to try adding conditional logic within the useEffect so you only trigger the dispatch if you don't already have a profile.

import "./styles.css";
import { useDispatch, useSelector } from "react-redux";
import { useEffect, useCallback } from "react";
import { getCurrentProfile } from "./action";

export const Profile = () => {
  const dispatch = useDispatch();
  const profileReducer = useSelector((state) => state.profile);
  const authReducer = useSelector((state) => state.auth);
  const { profile, error, loading } = profileReducer;
  // read more about this here: https://stackoverflow.com/questions/58624200/react-hook-useeffect-has-a-missing-dependency-dispatch
  const stableDispatch = useCallback(dispatch, []);

  useEffect(() => {
    if (!profile) {
      stableDispatch(getCurrentProfile());
    }
  }, [profile, stableDispatch]);

  const { user } = authReducer;

  console.log("loading", loading);
  console.log("profile", profile);

  return loading && profile === null ? <div>Spinner</div> : "Actual Profile";
};

export default Profile;

Also, it doesn't seem like you're currently doing anything with the loading piece of state–at least from what you've shared here. You might want to dispatch an action indicating that you're loading before you start the fetch and then it will be set to false when you get the response.

Check out this codesandbox for reference: https://codesandbox.io/s/focused-kilby-gd2nr?file=/src/App.js

Reducers:

const initialState = {
  profile: null,
  loading: false
};
export const profile = (state = initialState, action) => {
  const { type, payload } = action;

  switch (type) {
    case "LOADING_PROFILE":
      return {
        ...state,
        loading: true
      };
    case "GET_PROFILE":
      return {
        ...state,
        profile: payload,
        loading: false
      };

    case "PROFILE_ERROR":
      return {
        ...state,
        error: payload,
        profile: null
      };
    case "CLEAR_PROFILE":
      return {
        ...state,
        profile: null,
        loading: false
      };
    default:
      return state;
  }
};

export const auth = (state = {}, action) => {
  return state;
};

Action Creator:

import axios from "axios";
export const getCurrentProfile = () => async (dispatch) => {
  try {
    dispatch({ type: "LOADING_PROFILE" });
    const res = await axios.get("https://jsonplaceholder.typicode.com/users/1");
    console.log(res);
    dispatch({
      type: "GET_PROFILE",
      payload: res.data.data
    });
  } catch (err) {
    dispatch({
      type: "PROFILE_ERROR",
      payload: { msg: err.response.statusText, status: err.response.status }
    });
  }
};

index.js

import { StrictMode } from "react";
import ReactDOM from "react-dom";
import { Provider } from "react-redux";
import { createStore, combineReducers, applyMiddleware } from "redux";
import { profile, auth } from "./reducers";
import App from "./App";
import thunk from "redux-thunk";

const store = createStore(
  combineReducers({
    profile,
    auth
  }),
  applyMiddleware(thunk)
);

const rootElement = document.getElementById("root");
ReactDOM.render(
  <StrictMode>
    <Provider store={store}>
      <App />
    </Provider>
  </StrictMode>,
  rootElement
);

2 of 2
2

Well i solved it by dispatching 'getCurrentProfile' not 'getCurrentProfile()' turns out using it like a function causes continuously firing off.

   const profileReducer = useSelector((state) => state.profile);
const authReducer = useSelector((state) => state.auth);
const { profile, error, loading } = profileReducer;
const dispatch = useDispatch();

useEffect(() => {
    if (!profile) {
        console.log("It worked")
        dispatch(getCurrentProfile());
    }




}, [dispatch(getCurrentProfile)])
🌐
Reddit
reddit.com › r/learnprogramming › [react] useeffect won't work until i refresh page manually
r/learnprogramming on Reddit: [REACT] useEffect won't work until I refresh page manually
April 18, 2022 -

So I have a log in page with a login form and a user page with a logout button.

I'm using useEffect on both the loginpage and userpage.

My logout button and useeffect works fine and looks like this. It goes back to the home page if I logout from the userpage

useEffect(()=> {

if(!userInfoFromStorage){

history("/")

} }, [userInfoFromStorage, history])

In my log in page however, after putting in the correct details for login. The submit button doesnt do anything until I refresh the page manually, which then takes me to my userpage. the useeffects in login looks like this:

useEffect(()=> {

if(userInfoFromStorage && userInfoFromStorage.isAdmin){

history("/user")

}}, [userInfoFromStorage, history])

🌐
CodingDeft
codingdeft.com › posts › react-useeffect-hook
Complete Guide to useEffect Hook in React | CodingDeft.com
May 29, 2021 - So if we update our code accordingly ... to useEffect). This is to ensure that the useEffect runs only once when the component is mounted and not when the component is updated or re-rendered....
🌐
GitHub
github.com › WordPress › gutenberg › discussions › 51624
useEffect function running after page refresh, how to avoid this? · WordPress/gutenberg · Discussion #51624
June 18, 2023 - I didn't find a solution why useEffect running on page restart, but I change my code to check if sidebar block presented as section inner block before adding it or removing, this solved the problem with overwriting blocks during transformation, here is my code:
Author   WordPress
🌐
GitHub
github.com › inertiajs › inertia › issues › 1547
Triggering router.reload inside useEffect() would not work as expected · Issue #1547 · inertiajs/inertia
May 11, 2023 - You switched accounts on another tab or window. Reload to refresh your session. ... When calling router.reload inside the useEffect hook with specific props, it returns a 409 error and doesn't reload the specified props. However, when wrapping router.reload in a setTimeout of 0ms (as suggested in: https://laracasts.com/discuss/channels/inertia/using-routerreload-with-laravel-inertia-and-react), it works as expected.
Published   May 11, 2023
Author   stefano-ciotola
Find elsewhere
🌐
Reddit
reddit.com › r/reactjs › how do i stop useeffect from running after every refresh?
How do I stop useEffect from running after every refresh? : r/reactjs
March 6, 2021 - no useEffect will run on page reload no matter what except you put in any kind of if clause to only fire the dispatch by condition ... A page reload completely restarts the app, so your useEffect will always think that it's the first time it has run. ... (unless by reloading the page you mean ...
🌐
Reddit
reddit.com › r/reactjs › useeffect logics : use state value without running each time it refresh
r/reactjs on Reddit: useEffect logics : Use state value without running each time it refresh
December 1, 2021 -

Hi there!

I have been looking for a way to solve this issue for a while, and I have a hard time googling it.

Pseudo code example :

useEffect(() => {     
    setCopy(Data) 
}, [Switch]); 

It's not exactly what I'm doing, but the principale is the same.

I would like to put Data in Copy, but only when Switch change.

The issue is, I have to put Data in the dependency array or I get eslint warning. But I can't do that, because it will run the effect when data is changing, and I don't want that.

I tried to use a callback, but same issue, the callback will change each time data change, and will launch the effect.

Is there a way to do this? I have been trying many things, but can't find a solution.

And I don't want to disable ESLint.

Thank you!

🌐
Stack Overflow
stackoverflow.com › questions › 67557248 › react-useeffect-not-working-on-page-refresh
React UseEffect not working on page refresh
May 16, 2021 - I am using Redux and I dispatch action on useeffect. At first, It works but after page reloads all information become null and i get this error TypeError: Cannot read property 'mainImage' of null. In redux dev tools, it doesnot even call the action and my redux store state it is null. What could be possible error? My other components are working fine , even after reloading page and I am using same method in other components also. I have even checked if my response data are loading or not.
🌐
GitHub
github.com › facebook › react › issues › 14066
State variable not updating in useEffect callback? · Issue #14066 · facebook/react
November 1, 2018 - You switched accounts on another tab or window. Reload to refresh your session. ... Do you want to request a feature or report a bug? Bug, maybe? Although thinking about it more makes me think I've misunderstood something. What is the current behavior? scroll state variable updates in rendered output but not inside handleScroll event callback.
Author   evolutionxbox
Top answer
1 of 1
4

When you switch from one user to another, the component won't remount so:

const [user, setUser] = useState(location.state);

Is stuck on the previous location.state value. Therefore it may be stuck on one which does not pass the condition !user?.id.

I suspect this will be the case because location.state is the push state, and that means if you visit this page from the outside, or if you click on a <Link> like yours which does not redefine the push state, it will empty. But I think using this in the first place was an accident. Please note the location.state property is not related to the params. It's an entirely different mechanism that looks irrelevant here.

So the if condition does not pass and the fetch never happens.

The use of location.state as a default value does not make sense. I think this should just be null or undefined.

And then make the condition in the effect actually check the param and not the user you already have (might not even have it yet), or when you fetch the first user, it will never evaluate to true inside that if condition ever again since user.id is populated.

It also doesn't make sense for user to be in the effect deps. That would create an infinite loop with these other changes (I think maybe that's when you added conditions that didn't make sense). You only care about if the URL ID changes in that effect and that's it.

import React, { useState, useEffect } from 'react'
import { Link, useParams, useLocation } from 'react-router-dom';

function UserDetail() {
    const { id } = useParams();
    const location = useLocation();
    const [user, setUser] = useState();
    console.log(location)

    useEffect(() => {
        if (id !== undefined) {
            fetch(`https://jsonplaceholder.typicode.com/users/${id}`)
                .then((res) => res.json())
                .then((data) => setUser(data))
            console.log("if olan")
        }

    }, [id])


    return (
        <div>
            <h2>
                User Detail
            </h2>

            {user && <pre>
                {JSON.stringify(user, null, 2)}
            </pre>}
            <Link to={`/users/${Number(id) + 1}`}>Next User</Link>
        </div >
    )
}

export default UserDetail
🌐
freeCodeCamp
freecodecamp.org › news › most-common-react-useeffect-problems-and-how-to-fix-them
React.useEffect Hook – Common Problems and How to Fix Them
October 14, 2021 - What is going on here?! Let's explain. The reason our component is re-rendering is because our useEffect dependency is constantly changing. But why? We are always passing the same object to our hook! While it is true that we are passing an object with the same key and value, it is not the same object exactly.
🌐
Stack Overflow
stackoverflow.com › questions › 74905022 › react-useeffect-stops-working-populating-state-on-page-refresh
React useEffect stops working (populating state) on page refresh
I am working on a dictionary and using my API to fetch the words of a particular user. In a nutshell, I have one useEffect that fetches user's words (with an argument wordText which is an input value of a search bar - I need it to see if a word is already present in the vocabulary). I then render the words with words.map. The problem is that when I reload the page I get words.map is not a function error, indicating that either words is empty or is not an array.
🌐
React
react.dev › reference › react › useEffect
useEffect – React
If your Effect is doing something ... delay is noticeable (for example, it flickers), replace useEffect with useLayoutEffect. If your Effect is caused by an interaction (like a click), React may run your Effect before the browser paints the updated screen. This ensures that the result of the Effect can be observed by the event system. Usually, this works as ...