Формировать состояния в реактивной редукции

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

Я поддерживаю все мое состояние формы в редуксе. Например:

const defaultState = { 
    touched: { email: false, password: false },
    loginFormErrors: {email: '', password: ''},
    emailValid: false,
    passwordValid: false,
    formValid: false
}

Некоторые из этих значений состояния обновляются validateLoginFields (редуктор), который вызывается при отправке действия VALIDATE_LOGIN_FIELDS

const validateLoginFields = (state, action) => {
  const newLoginFormErrors = {}
  let emailValid = state.emailValid
  let passwordValid = state.passwordValid
  let formValid = state.formValid

  switch(action.key) {
    case 'email':
    if(!action.value){
        emailValid = false
        newLoginFormErrors.email = ''
    }else{
        const pattern = new RegExp("[^\\s@]+@[^@\\s]+\\.[^@\\s]+")
        emailValid = pattern.test(action.value)
        newLoginFormErrors.email = emailValid ? '' : 'Invalid email'
    }
    break
    case 'password':
    if(!action.value){
        passwordValid = false
        newLoginFormErrors.password = ''
    }else{
        passwordValid = action.value.length >= 6
        newLoginFormErrors.password = passwordValid ? '': 'Password is too short!';
    }
    break
    default:
    break
  }

  formValid = emailValid && passwordValid
  const loginFormErrorData = {}
  Object.assign(loginFormErrorData, state.loginFormErrors, newLoginFormErrors)
  const newState = {}
  Object.assign(newState, state, { loginFormErrors: loginFormErrorData, emailValid: emailValid, passwordValid: passwordValid, formValid: formValid })
  return newState
}

У меня есть несколько вопросов здесь:

  1. Правильно ли я поступаю, сохраняя детали проверки моей формы на стороне клиента (например, valid, touch, formErrors и т. Д.) В Redux, или мне лучше использовать локальное состояние для этой цели? Так как я также храню данные, связанные с аутентификацией, в избыточном, я просто чувствовал себя немного более комфортно, имея Redux в качестве единственного источника правды для всего, но все же хочу подтвердить эту идею с остальной частью сообщества.

  2. Является ли это нормально для функции редуктора, как validateLoginFields выполнить проверки на стороне клиента, как я показал в моем примере? Он возвращает новое состояние - что делает редуктор, но эта функция также выполняет проверки для меня... Я чувствую, что что-то здесь не так и может быть сделано лучше... Я имею в виду более обобщенную проверку? Является ли редуктор подходящим местом для проверки?

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

Я попробовал использовать Redux-form и React-redux-form, эти библиотеки великолепны, но сейчас я хочу выполнить эти проверки самостоятельно для обучения.

ОБНОВИТЬ:

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

export function validateLoginFields(key, value) {
  const newLoginFormErrors = {}
  let emailValid = false
  let passwordValid = false
  let formValid = false

  switch(key) {
    case 'email':
    if(!value){
      emailValid = false
      newLoginFormErrors.email = ''
    }else{
      const pattern = new RegExp("[^\\s@]+@[^@\\s]+\\.[^@\\s]+")
      emailValid = pattern.test(value)
      newLoginFormErrors.email = emailValid ? '' : 'Invalid email'
    }
    break
    case 'password':
    if(!value){
      passwordValid = false
      newLoginFormErrors.password = ''
    }else{
      passwordValid = value.length >= 6
      newLoginFormErrors.password = passwordValid ? '': 'Password is too short!';
    }
    break
    default:
    break
  }

  formValid = emailValid && passwordValid

  return { type: VALIDATE_LOGIN_FIELDS, newLoginFormErrors, emailValid, passwordValid, formValid }
}

С вышеупомянутым изменением я поставил себя в другой вопрос, куда я возвращаюсь emailValid=false, даже если я проверяю поле пароля. Если в моем предыдущем состоянии emailValid=true тогда это становится ложным. Это происходит потому, что я переопределяю свои значения состояния. Есть ли способ получить доступ к текущему состоянию в actionCreator, чтобы я мог возвращать те же значения состояния, если ничего не изменилось?

Но, согласно этому сообщению, доступ к состоянию в actionCreator - не лучший способ.

Доступ к состоянию Redux в создателе действий?

1 ответ

Я положил подтверждение в мои редукторы. Редукторы принимают предыдущее состояние и действие, а затем возвращают новое состояние.

Вот структура простого магазина:

{customer: {
  firstName: "FatBoy",
  lastName: "Slim",
  email: 'foo@bar.com',
  validationErrors: {}
}}

Вот редуктор, который обновляет клиента и выполняет проверку адреса электронной почты:

function customerReducer(state = {}, action) {
   switch (action.type) {
     case 'UPDATE_CUSTOMER':
       let validationErrors = {}
       let emailError = validateEmail(action.customer.email);
       if (emailError) {
         validationErrors['email'] = emailError;
       }   
       return {...state, ...action.customer, validationErrors};
     default:
       return state;
   }
}

(Примечание. Это псевдокод. Никто никогда не запускал его. Он вам нужен, чтобы понять суть.)

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

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