Mantofka
Mantofka

Reputation: 286

Context API doesn't update on Next.JS

For the first time I tried Next.JS. I implemented Context API, but It never work for me. I mean, I only can see initial values, but not the updated ones. This is how I implemented Context API:

This is the file where I create context and give initial values, like user: "test"

userContext.js


const UserContext = createContext({
  user: "test",
  fetchUser: function (data) {},
});

export const UserContextProvider = ({ children }) => {
  const [userData, setUserData] = useState(null);

  const fetchUserHandler = (data) => {
    setUserData(data);
  };

  const context = { user: userData, fetchUser: fetchUserHandler };

  return (
    <UserContext.Provider value={context}>{children}</UserContext.Provider>
  );
};

export default UserContext;

This is where I try to change the data inside Context Api state.

_app.js

import { createGlobalStyle, ThemeProvider } from "styled-components";
import UserContext, { UserContextProvider } from "../context/UserContext";

import { auth, db } from "../firebase";

const GlobalStyle = createGlobalStyle`
html{
  font-size: 62.5%;
}

body {
  @import url('https://fonts.googleapis.com/css2?family=Open+Sans:wght@400;600;700&display=swap');
}

* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}
`;

const theme = {
  dark: {
    background: "#000",
  },
  light: {
    background: "#fff",
  },
};

function MyApp({ Component, pageProps }) {
  const [userInfo, setUserInfo] = useState(null);
  const userCtx = useContext(UserContext);

  useEffect(() => {
    let isMounted = true;
    if (isMounted) {
      auth.onAuthStateChanged((authedUser) => {
        if (authedUser) {
          // If logged in
          getUserID(authedUser.uid);
        } else {
          // If logged out
          console.log("Logged out");
        }
      });
    }
  }, []);

  const getUserID = (userId) => {
    // ommited sensitive data, but the data is fetched correctly
    setUserInfo(doc.data());
  };

  useEffect(() => {
    userInfo !== null && userCtx.fetchUser(userInfo);
  }, [userInfo]);

  return (
    <>
      <GlobalStyle />
      <ThemeProvider theme={theme}>
        <UserContextProvider>
          <Component {...pageProps} />
        </UserContextProvider>
      </ThemeProvider>
    </>
  );
}

export default MyApp;

MessageHeads.js

import { useState, useEffect } from "react";
import {
  Container,
  HeaderPart,
  ConversationContainer,
  Button,
  UserContainer,
  UserIcon,
  UserInfo,
  UserName,
  LastMessage,
} from "../styled-components/MessageHeads";

import { useContext } from "react";
import UserContext from "../context/userContext";

export default function MessageHeads() {
  const userCtx = useContext(UserContext);

  useEffect(() => {
    console.log(userCtx.user);
  }, []);

  return (
    <Container>   
        <Button onClick={() => console.log(userCtx)}>
          Create conversation
        </Button>
    </Container>
  );
}

But in the end, I still get that the userCtx.user is "test" and not some other value.

Upvotes: 3

Views: 2910

Answers (1)

Mantofka
Mantofka

Reputation: 286

Okey, I managed to solve this problem. So what I saw (credit to the terminal 😄) is that I didn't imported UserContext and UserContextProvider properly.

That is how I imported: import UserContext, { UserContextProvider } from "../context/UserContext";

And it should be (only UserContext changed to userContext) import UserContext, { UserContextProvider } from "../context/userContext";

Despite the fact, I even spotted odd behaviour where from MessageHeads.js I can updare my Context API, but from _app.js I can't. The data stays the same.

Upvotes: 1

Related Questions