Пользовательский интерфейс React не обновляется при возврате <Navigate to="/Login" />

Я просто пытаюсь вызвать функцию submitformdata(data), которая отправляет данные в базу данных и по завершении возвращает строку successRegister. После возврата этой строки успеха я хочу перейти прямо на страницу входа без дальнейшего взаимодействия с пользователем. То, что у меня ниже, работает без ошибок, но не переходит на страницу \Login, даже если для переменной toLogin установлено значение successRegister, проверенное оператором журнала консоли. Я ожидаю, что это что-то концептуальное, что мне не хватает в отношении того, как обновляются состояния пользовательского интерфейса.

export default function Register() {

const [toLogin, setToLogin] = React.useState("failRegister");

const handleSubmit = (event) => {
    event.preventDefault();

    const data = new FormData(event.currentTarget);

    if (data.get('email') === '' || data.get('password') === '' || data.get('verifypassword') === '' || data.get('firstName') === '' || data.get('lastName') === '') {
        return
    }

    submitformdata(data).then(response => {

        setToLogin(response);

        if (toLogin === "successRegister") {
            return <Navigate to = "/Login" />;
        }
    });
};

return (code here for the Register page);
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
0
0
59
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Во-первых, значение «toLogin» не меняется сразу. Пожалуйста, перепроверьте концепцию хука здесь https://reactjs.org/docs/hooks-state.html

Чтобы обновить пользовательский интерфейс, вам нужно использовать переменную «toLogin» в вашем коде возврата.

Если вы используете react-router-dom для маршрутизации, вы можете использовать хук useNavigate(), как показано ниже, но все же это зависит от версии react-router-dom.

И для вас информация об использовании хуков useState является асинхронной, и каждый раз, когда вы обновляете переменные состояния, реакция будет повторно отображать компонент, таким образом, вместо того, чтобы включать <Navigate to = "/login"> внутреннюю функцию, которую вы можете включить в сам компонент рендеринга. {переменная состояния и }.

import {useNavigate} из "react-router-dom";

function Invoices() {
  let navigate = useNavigate();
  return (
    <div>
      <NewInvoiceForm
        onSubmit = {async (event) => {
          let newInvoice = await createInvoice(
            event.target
          );
          navigate(`/invoices/${newInvoice.id}`);
        }}
      />
    </div>
  );
}
Ответ принят как подходящий

Есть несколько вещей, которые вы должны учитывать при использовании реактивных хуков. Во-первых, мне нужно использовать реагирующий хук или я могу использовать обычную переменную? Если вы можете использовать простую переменную и вам не нужно сохранение состояния между рендерингами, используйте переменную. Если вам необходимо сохранение между рендерингами, используйте хук! all и не требует, чтобы он был постоянным между рендерами! С логикой, описанной выше, мы можем видеть, что в этом случае нет реальной причины или необходимости в этом хуке. Проверьте код ниже.

import { useNavigate } from 'react-router-dom'; //using v6 here.

...

//No hooks required for persistence between renders.
//You can use a hook if you wish to handle errors and display them.
const navigate = useNavigate();

const handleSubmit = (event) => {
    event.preventDefault();

    const data = new FormData(event.currentTarget);

    if (data.get('email') === '' || data.get('password') === '' || data.get('verifypassword') === '' || data.get('firstName') === '' || data.get('lastName') === '') {
        return
    }

    submitformdata(data).then(response => {

        //In this case the response must be "successRegister"

        if (response === "successRegister") {
            //returning <Navigate to = "/Login" /> doesn't work because it is the return of the onSubmit function.
            navigate("/Login");
            //No return needed for this function.
        }
    });
};

return (code here for the Register page);

Более подробная информация

Lets explain why your code doesn't work as you anticipate. First, React hook state updates are asynchronous meaning they don't happen immediately! So when you setToLogin using your dispatch of the useState hook you haven't actually updated the toLogin "variable" or toLogin state. So all the if statement see's is the original "failRegister" value that it was initialized to.
Second, you aren't returning a UI component to the ReactDOM you are returning a react component (JSX) to the onSubmit function (which doesn't render anything). Using the react-router-dom version 6 you can useNavigate hook to handle React Navigation between pages.

The reason I chose the code above is because I don't find a reason to set a variable to the response object if all we are going to do is a quick if statement to compare the response with a string... So I just compared directly with no intermediate variable and left all the rest of your code the same (removing the unused hook and adding the new navigation hook). To make your register code more robust you could add an "else" block to your if statement that and add a hook that would handle errors and display them appropriately.

Happy coding and learning.

Спасибо. Очень информативный и исчерпывающий ответ.

Terence 01.04.2022 23:15

Другие вопросы по теме