Сообщение NextJS Display API на странице

У меня есть форма входа. Пользователь вводит свое имя пользователя/пароль в форму и отправляет ее. Форма использует fetch() для отправки запроса к серверному API и получения ответа.

Я хочу отобразить сообщение от API на странице. Это будет {apiErrorMessage}

Например, учетная запись пользователя может быть заблокирована. Пароль может быть неправильным. Адрес электронной почты не может быть подтвержден.

В старые времена я делал это, используя частичные обновления страниц AJAX, используя страницы C# Razor. Это проект NextJS, и я понятия не имею, как это сделать.

Должен ли я использовать рендеринг на стороне сервера? Должен ли я использовать рендеринг на стороне клиента? Хук UseEffect()?

Я все еще хотел бы, чтобы страница выглядела хорошо для целей SEO.

Я думаю, может быть, нам нужно использовать вторую страницу, чтобы сделать это с SSR? Страница LoginResult или что-то в этом роде?

Любая помощь приветствуется :) Спасибо!

      const Login = () => {

    let apiErrorMessage = "";

    const loginFormSubmit = async (event) => {

    event.preventDefault()

    // Get data from the form.
    const data = {
      username: event.target.username.value,
      password: event.target.password.value,
    }

    const JSONdata = JSON.stringify(data)

    const response = await fetch(`/api/login`)

    const result = await response.json()

    if (response.ok){
        router.push('/dashboard');
    }
    else {
        // Get the error message from API
        apiErrorMessage = result.message;
    }
}


return (
        <div>
            <form onSubmit={loginFormSubmit}>
                <div className="mb-4">
                    <label htmlFor="username"><b>Username</b></label>
                    <input type="text" id="username" required/>
                </div>
                <div className="mb-4">
                    <label htmlFor="password"><b>Password</b></label>
                    <input type="password" id="password" required/>
                </div>
                <button type="submit">Login</button>
            </form>
        </div>
        <div>
            <p>{apiErrorMessage}</p>
        </div>
 )
}

export default Login;

2 ответа

вам не нужно создавать страницу, для которой вы можете создать простой хук useState:

      const [errorMsg,setErrorMsg] = useState('');

когда пользователь не может войти в систему:

      else {
   // Get the error message from API
   setErrorMsg(result.message)
}

Теперь под вашим<form>вы создаете<div>это будет показано только тогда, когдаerrorMsg !== '':

      {errorMsg === '' ? '' : (<div>
   <p>login failed : ${errorMsg}</p>
</div>)}

так просто, как, что.

Я не могу придумать причину, по которой вам может понадобиться хороший SEO для компонента входа в систему, который просто принимает пользовательский ввод и возвращает ответ об ошибке или перенаправляет их на страницу.

Так как все внутри/pagesэтоClient componentпо умолчанию, я думаю, лучше всего просто использовать состояние и эффекты. Вот пример с небольшими изменениями в вашем коде:

      import {useState} from 'react';
import { useRouter } from 'next/navigation';

const Login = () => {
  const [apiErrorMessage, setApiErrorMessage] = useState('');
  const router = useRouter();

  const loginFormSubmit = async (event: any) => {
    event.preventDefault();

    // Get data from the form.
    const data = {
      username: event.target.username.value,
      password: event.target.password.value,
    };

    const JSONdata = JSON.stringify(data);

    const response = await fetch(`/api/login`);

    const result = await response.json();

    if (response.ok) {
      router.push("/dashboard");
    } else {
      // Get the error message from API
      setApiErrorMessage(result.message);
    }
  };

  return (
    <div>
      <div>
        <form onSubmit={loginFormSubmit}>
          <div className="mb-4">
            <label htmlFor="username">
              <b>Username</b>
            </label>
            <input type="text" id="username" required />
          </div>
          <div className="mb-4">
            <label htmlFor="password">
              <b>Password</b>
            </label>
            <input type="password" id="password" required />
          </div>
          <button type="submit">Login</button>
        </form>
      </div>
      <div>
        <p>{apiErrorMessage}</p>
      </div>
    </div>
  );
};

export default Login;
Другие вопросы по тегам