Контекстный API не обновляется на Next.JS

#reactjs #next.js #context-api

Вопрос:

В первый раз я попробовал Next.JS. Я реализовал контекстный API, но он никогда не работал для меня. Я имею в виду, что я могу видеть только начальные значения, но не обновленные. Вот как я реализовал Контекстный API:

Это файл, в котором я создаю контекст и даю начальные значения, такие как 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;
 

Здесь я пытаюсь изменить данные в состоянии Api контекста.

_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;700amp;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 amp;amp; 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>
  );
}
 

Но, в конце концов, я все равно понимаю, что userCtx.user это "test" так, а не какая-то другая ценность.

Комментарии:

1. Где вы используете userCtx.user

2. Итак, я создал отдельный компонент, затем использовал useContext(UserContext); и из useEffect я получаю начальное значение «test», но не обновленное

3. и userCtx.user в приличиях ли это useEffect() ?

4. Нет, но я не думаю, что это решило бы проблему, потому что я добавил onclick событие на кнопке , которое console.log userCtx.user , но дает тот же начальный результат

5. Я добавил MessageHeads.js часть вопроса, чтобы посмотреть, откуда это происходит console.log

Ответ №1:

Ладно, мне удалось решить эту проблему. Итак, то, что я увидел (кредит терминалу😄), заключается в том, что я не импортировал UserContext и UserContextProvider должным образом.

Вот как я импортировал: import UserContext, { UserContextProvider } from "../context/UserContext";

И это должно быть (только UserContext изменено на userContext ) import UserContext, { UserContextProvider } from "../context/userContext";

Несмотря на этот факт, я даже заметил странное поведение, когда MessageHeads.js я могу обновить свой контекстный API, но _app.js не могу. Данные остаются прежними.