Why does my app not get the latest data from state within useEffect?
I have a component. Article.js that imports the context with useContext.
import React, { useContext, useEffect } from "react";
import ArticleContext from "../../context/article/articleContext";
import Spinner from "../layout/Spinner";
import { documentToHtmlString } from "@contentful/rich-text-html-renderer";
const Article = ({ match }) => {
const articleContext = useContext(ArticleContext);
const { getArticle, loading, article } = articleContext;
useEffect(() => {
getArticle(match.params.slug);
}, []);
/**
* When i use article anywhere here, it is undefined.
*/
// this will be undefined
console.log(article);
// Even though getArticle has updated the state via the reducer.
if (loading) {
return <Spinner />;
} else {
return (
<main>
<section className='container'>
{/* the idea is to put the content here */}
</section>
</main>
);
}
};
export default Article;
This is my context within a file called articleState.js
import React, { useReducer } from "react";
import ArticleContext from "./articleContext";
import ArticleReducer from "./articleReducer";
import { SET_LOADING, GET_ARTICLE } from "../types";
import client from "../../contentful";
const ArticleState = props => {
//Initial State
const initialState = {
article: {},
loading: false
};
// Set the reducer we want to use
const [state, dispatch] = useReducer(ArticleReducer, initialState);
//set up your actions
//set loading
const setLoading = () => {
dispatch({ type: SET_LOADING });
};
//get a single article
const getArticle = async slug => {
setLoading();
const res = await client.getEntries({
content_type: "article",
"fields.slug": slug
});
dispatch({ type: GET_ARTICLE, payload: res.items });
};
return (
<ArticleContext.Provider
value={{
article: state.article,
loading: state.loading,
getArticle
}}
>
{props.children}
</ArticleContext.Provider>
);
};
export default ArticleState;
When checking the chrome developer toolbar, the state successfully updates. I see the article content i pulled down from contentful. It is in my state.
My only issue is when i try to get the data from article it's undefined.
Here's my reducer articleReducer.js
import { SET_LOADING, GET_ARTICLE } from "../types";
export default (state, action) => {
switch (action.type) {
case SET_LOADING:
return {
...state,
loading: true
};
case GET_ARTICLE:
return {
...state,
article: action.payload,
loading: false
};
default:
return state;
}
};
Thank you for reading this and for any help.