Naman Kedia
Naman Kedia

Reputation: 93

useEffect not triggers when rendering a component

I am clicking on a single post on homepage that'll send me to the clicked post's page. At this component's rendering I am dispatching an action from useEffect that will get the post data from backend. But useEffect doesn't gets triggered even a single time but page render's twice. Please help

import {
  Container,
  Typography,
  LinearProgress,
  CircularProgress,
  Paper
} from '@material-ui/core';
import React, {
  useEffect
} from 'react';
import {
  getPost
} from "../../actions/posts";
import Navbar from '../Navbar/Navbar';
import {
  useDispatch,
  useSelector
} from 'react-redux';
import {
  useParams
} from 'react-router-dom';
import useStyles from "./styles";

const PostDetails = () => {
    const dispatch = useDispatch();
    const {
      id
    } = useParams();
    const classes = useStyles();
    const {
      post,
      isLoading
    } = useSelector((state) => (state.posts));

    console.log(post);
    useEffect(() => {
      console.log(post);
      dispatch(getPost(id));
    }, [id, dispatch]);

    return ( < div >
        <
        Navbar color = "#808080" / > {
          isLoading ? ( < div > < LinearProgress / > < /div>) : 
            ( < Container className = {
                classes.root
              } >
              <
              Typography variant = "h1" > {
                post.title
              } < /Typography> <
              /Container>)}</div > )
          }
          export default PostDetails

My action:

export const getPost = (id) => async(dispatch) => {
  try {
    dispatch({
      type: "START_LOADING"
    });
    const {
      data
    } = await api.fetchPost(id);
    dispatch({
      type: "FETCH_POST",
      payload: {
        post: data
      }
    });
    dispatch({
      type: "END_LOADING"
    });
  } catch (error) {
    console.log(error);
  }
};

reducer:

export default (state = {
  isLoading: true,
  posts: []
}, action) => {
  switch (action.type) {
    case "START_LOADING":
      return { ...state,
        isLoading: true
      };

    case "FETCH_POST":
      return { ...state,
        post: action.payload.post
      };

    case "FETCH_ALL":
      return { ...state,
        posts: action.payload.data,
        currentPage: action.payload.currentPage,
        numberOfPages: action.payload.numberOfPages
      };

    case "CREATE":
      return { ...state,
        posts: [...state.posts, action.payload]
      };

    case "END_LOADING":
      return { ...state,
        isLoading: false
      };

    default:
      return "";
  }
}

My backend is fine since when i run the api request on localhost to backend it sends me a JSON object with post's data.

Upvotes: 2

Views: 3604

Answers (2)

Him Ho
Him Ho

Reputation: 77

dispatch(findPost(id)); //No findPost in ../../actions/posts

There is no findPost action. Do you think you should change it to getPost

dispatch(getPost(id)); 

Upvotes: 0

Muhammed Jaseem
Muhammed Jaseem

Reputation: 830

UseEffect gets triggered only when the values given inside the square brackets change. So, if you want it to get triggered only when loading the page for the first time, leave it blank.

useEffect(() => {
      console.log(post);
      await dispatch(findPost(id));
    }, []);

Upvotes: 4

Related Questions