В каком месте правильно диспатчить данные в Redux

долгое время работал с беком и тут пришлось перепрыгнуть на фронт, сейчас на этапе знакомства с React. У меня вопрос, я в своем приложении для хранения состояния использую Redux и не пойму как правильно и где диспатчить в него данные

У меня есть роутер, с action по которому указана функция обработчик

  const router = createBrowserRouter([
{
  path: "/", 
  element: <Layout />, 
  loader: getUser,
  children: [
    {
      path: "", 
      element: <Home />
    },
    {
      path: "auth/registration", 
      element: <RegistrationForm />,
      action: registrationUser
    },
    {
      path: "auth/login", 
      element: <LoginForm />
    },
  ]
},
])

 return <RouterProvider router={router} />
}

Сам метод расписывать не буду, он просто сохраняет данные пользователя и кладет токен с бека в localStorage, но он лежит в отдельном файле registrationUser.js в папке actions

В компоненте у меня такая логика

useEffect(() => {
    document.title = 'Registration'

    if (registrationResponse?.errors) {
        setErrors(registrationResponse.errors)
    }

    if (!registrationResponse?.errors) {
        dispatch(addUser({
            firstname: registrationResponse?.firstname,
            lastname: registrationResponse?.lastname,
            username: registrationResponse?.username,
            slug: registrationResponse?.slug,
            email: registrationResponse?.email,
            avatar: null
        }))

        setRegistrationData({
            firstname: "",
            lastname: "",
            username: "",
            slug: "",
            email: "",
            password: "",
    });
}
}, [registrationResponse])

т.е. я диспатчу данные через useEffect

Я хотел сделать немного по другому, хотел повесить на кнопку onClick обработчик условно вот так

const addUserToStorage = (e) => {
    e.preventDefault();

    dispatch(addUser({
        firstname: registrationResponse?.firstname,
        lastname: registrationResponse?.lastname,
        username: registrationResponse?.username,
        slug: registrationResponse?.slug,
        email: registrationResponse?.email,
        avatar: null
    }));
}

что бы при клике на кнопку, данные записывались в Redux, НО! так у меня сделать не получилось, тк моя форма использует вот это из Remix/React Router и соответственно в Redux при onClick ничего не попадало, а вот через useEffect все ок

Подскажите как лучше то, через action в роутах, <Form и записи через useEffect, или отказаться от этого и по простому, использовать для формы обычный тег , и там обработчик повесить?


Ответы (1 шт):

Автор решения: Danri

Мой личный совет: текущий подход с useEffect - правильный. Диспатч данных из useActionData в Redux через useEffect - это стандартный паттерн для интеграции роутер-экшенов и Redux.

По причине того, что функция action должна быть чистой (только обработка запроса и возврат данных). Диспатч в Redux - это побочный эффект, который выполняется после получения результата, то есть в компоненте.

Оставьте вариант с useEffect.

→ Ссылка