Как использовать контекстный Api в Next.js

#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 странице, но затем, после перехода обратно на страницу индекса и повторной отправки, она работает