M
M
Maa-Kut2017-04-19 19:25:01
JavaScript
Maa-Kut, 2017-04-19 19:25:01

How to link React router and Redux reducers?

Good day to all.
Need help with this moment. I'm working on a React+Redux application with routing (SPA and all that). The application has a form, after filling which the user presses a certain button, the form is checked, the user is thrown to another "page" (ie, the route). Initially, I planned to do the form validation in the reducer: the whole state is visible there, and in general it is somehow logical, because it is the reducer that is responsible for updating the state of the application (including at the "valid/invalid" level).
The problem is that I don’t know how to make the same transition to the next page at the end of the check. Pulling push in the reducer seems to be wrong (this applies more to action creators). You can set some flags in the state in the reducer, seeing which the form, instead of rendering itself, initiates a transition to another page, but this one looks somehow crutch.
Share, plz, experience, who as in general solves similar problems?

Answer the question

In order to leave comments, you need to log in

1 answer(s)
I
Islam Ibakaev, 2017-04-20
@devellopah

just thinking out loud

// types
const types = {
  UPDATE_FIELD: 'UPDATE_FIELD',
};
//types

// operations
const updateField = (value, error) => (
  { type: types.UPDATE_FIELD, value, error }
);

// reducer
const initialState = { 
  values: {email: '', password: ''}, 
  errors: { email: '', password: '' } 
};

function someFormReducer(state = initialState, action) {
  switch(action.type) {
    case types.UPDATE_FIELD: {
      return { 
        values: { ...state.values, ...action.value }, 
        errors: { ...state.errors, ...action.error };
    }
  }
  
  return state;
}
// reducer

// так примерно выглядит global store
{
  ...
  ...
  form: {
    login: {
      values: {
        email: '',
        password: '',
      },
      errors: {
        email: '',
        password: ''
      }
    },
  }
}
// так примерно выглядит global store


import React from 'react';
import { validateEmail, validatePassword } from 'someValidateLibrary';
import { connect } from 'react-redux';
import { browserHistory } from 'react-router';
  
import { updateField } from 'path to operations file (action creators)' 

class SomeForm extends React.Component {
  
  handleValueChange = (e) => {
    const field = e.target.name;
    let error = '';
    
    if(field === 'email' && !validateEmail(field)) {
      error = "You email is so bad, seriously!";
    } 
    else if (!validationPassword(field) ) {
      error = "Your password is sucks!"
    }
    
    this.props.dispatch(
      updateField(
        { field: e.target.value.trim() }, 
        { field: error.trim() }
      )
    );
  } 

  proccessForm = () => {
    const { errors } = this.props;
    // если ошибок больше нет, то переход на другой роут
    if(!errors.email && !errors.password) {
      browserHistory.push('/home');
    } else {
      // your code here
    }
    
  }
  
  render() {
    const { values, errros } = this.props;
    
    return (
      // some ui
      <form onSubmit={this.proccessForm}>
        <p class="form-field">
          <input 
            type="email" 
            name="email" 
            onChange={this.handleValueChange} 
            value={values.email} 
          />
          <span>{errors.email}</span>
        </p>
        <p class="form-field">
          <input 
            type="text" 
            name="password" 
            onChange={this.handleValueChange} 
            value={values.password} 
          />
          <span>{errors.password}</span>
        </p>
        <button 
          type="submit" 
          disabled={!values.email && !values.password}>
            submit
        </button>
      </form>
    );
  }
}

const mapStateToProps = ({ form: { login } }) => (
  { values: login.values, errors: login.errors }
);
  

connect(mapDispatchToProps)(SomeForm);

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question