#javascript #reactjs #next.js #context-api
#javascript #reactjs #next.js #реагировать-контекст
Вопрос:
Сначала я хотел бы сказать, что я никогда не работал ни с next.js или контекстный api, так что, пожалуйста, потерпите меня.
В настоящее время я работаю над веб-приложением в Next.js где у меня есть несколько страниц, каждая из которых содержит форму. Я хотел бы иметь какое-то глобальное состояние, чтобы иметь возможность устанавливать и обновлять данные из каждой формы. Все данные формы вместе
Например: страница 1 = название, страница 2 = описание, …
Из того, что я прочитал в Интернете, я думал, что использования context api будет достаточно, но я уперся в стену. Когда я заполняю имя в первой форме, оно не сохраняется в глобальном состоянии, потому что оно не отображается на второй странице.
Я не понимаю, где я ошибся, поэтому любую помощь я более чем приветствую!
p.s. если я неправильно объяснил какую-то часть или забыл добавить фрагмент кода, пожалуйста, дайте мне знать.
businessContext.tsx
import { createContext, useState } from "react";
//accessible data
export interface BusinessContextData {
businessName: string;
handleBusinessName: (name: string) => void;
}
//default values
export const businessContextDefaultValue: BusinessContextData = {
businessName: "",
};
//provider
export const BusinessContext = createContext<BusinessContextData>(
businessContextDefaultValue
);
//hooks that components can use to change the values
export function useBusinessContextValue(): BusinessContextData {
const [businessName, setBName] = useState<string>("");
const handleBusinessName = (name: string) => {
setBName(name);
};
return {
businessName,
handleBusinessName,
};
}
_app.tsx
import type { AppProps } from "next/app";
import {
useBusinessContextValue,
BusinessContext,
} from "../context/businessContext";
import "../styles/global.css";
function MyApp({ Component, pageProps }: AppProps) {
const businessContextValue = useBusinessContextValue();
return (
<BusinessContext.Provider value={businessContextValue}>
<Component {...pageProps} />
</BusinessContext.Provider>
);
}
export default MyApp;
Страница формы BusinessName.tsx — name (должно сохранять данное имя в глобальном состоянии)
import { ChangeEvent, FormEvent, useContext, useState } from "react";
import { BusinessContext } from "../context/businessContext";
const IndexPage = () => {
const { handleBusinessName } = useContext(BusinessContext);
const router = useRouter();
const [businessNameState, setBusinessnameState] = useState<string>("");
const onSubmit = (e: FormEvent) => {
handleBusinessName(businessNameState);
router.push("/businessVision");
};
return (
...
<form onSubmit={(e: FormEvent) => onSubmit(e)}>
<div className="formInputRow">
<input
className="formInput"
type="text"
placeholder="Business name"
required
value={businessNameState}
onChange={(val: ChangeEvent<HTMLInputElement>) =>
setBusinessnameState(val.target.value)
}
/>
</div>
<button type="submit">
Next
</button>
</form>
...
);
};
export default IndexPage;
businessVision.tsx — должен отображать название компании из глобального состояния
import { ChangeEvent, FormEvent, useContext, useEffect, useState } from "react";
import { BusinessContext } from "../context/businessContext";
const BusinessVisionpage = () => {
const { businessName } = useContext(BusinessContext);
const router = useRouter();
const [businessVisionState, setBusinessVisionState] = useState<string>("");
return (
...
<h1>
<span>{businessName}</span>
</h1>
...
);
};
Ответ №1:
Ваш контекст настроен правильно, но вам нужно будет предотвратить <form>
поведение «отправить по умолчанию», чтобы переход на следующую страницу мог выполняться правильно.
const onSubmit = (e: FormEvent) => {
e.preventDefault(); // Prevents submit default behaviour
handleBusinessName(businessNameState);
router.push("/businessVision");
};
Комментарии:
1. Предотвращение поведения форм по умолчанию, похоже, не устраняет проблему. Может быть, это проблема с Next? Может быть, мне следует использовать getStaticProps или getServerSideProps для контекста?
2. Итак, даже с этим изменением нажатие кнопки отправки переходит к
/businessVision
, но имя, которое было введено, там не отображается?3. После сравнения и еще некоторой отладки я обнаружил, что это не работает только в первый раз, но после этого работает нормально
4. Что вы имеете в виду, это не работает в первый раз? При первом нажатии кнопки отправки имя не отображается на
/businessVision
странице после навигации? И если вы затем вернетесь и попробуете еще раз, это сработает?5. когда я нажимаю кнопку отправки в первый раз, она не показывает op на
/businessVision
странице, но затем, после перехода обратно на страницу индекса и повторной отправки, она работает