#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.loguserCtx.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
не могу. Данные остаются прежними.