@hollanditkzn

Как правильно использовать react redux при отправке формы?

Немножко не понятно, как в моем случае применять redux при отправке формы.
index.js
import React from 'react';
import ReactDOM from 'react-dom';
import  { Provider } from 'react-redux';
import { createStore, combineReducers } from 'redux';
import { Route, Switch } from 'react-router';
import { BrowserRouter } from 'react-router-dom';
import Auth from './component/AuthForm';
import Helmet from './aplication';

function user(state = {}, action){
    if(action.type === 'ADD_USER'){
        return [
            ...state,
            action.user
        ];
    }
    return state;
}

const store = createStore(user, window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__());

ReactDOM.render(
        <div>
            <Helmet title='Авторизация'/>
            <Provider store={store}>
            <BrowserRouter>
                    <Switch>
                        <Route exact path='/' component={Auth}/>
                        <Route path='/index' render={() => <div>Index</div>}/>
                    </Switch>
            </BrowserRouter>
        </Provider>
        </div>,
    document.getElementById('content')
);

И форма
import React, { Component } from 'react';
import { Redirect } from 'react-router';
import axios from 'axios';
import TextField from 'material-ui/TextField';
import RaiseButtin from 'material-ui/RaisedButton';
import MuiThemeProvider from 'material-ui/styles/MuiThemeProvider';
import injectTapEventPlugin from 'react-tap-event-plugin';

injectTapEventPlugin();

class UserForm extends Component{
    state = {
        form: {
            login: "",
            password: ""
        },
        error: "",
        redirectTo: "",
    };

    handleSubmit = e => {
        e.preventDefault();
//По логике тут я должен вынести dispather, верно? 
        axios.post('/api/user', this.state.form)
            .then(response => {
                if (response.data === false){
                    this.setState({ error: 'Неверный логин или пароль'});
                } else {
                    this.setState({redirectTo: '/index'});
                }
            })
            .catch(err => console.log(err));
    };

    handleChange = e => {
        const { name, value } = e.target;

        this.setState( prevState => ({
            form: {
                ...prevState.form,
                [name]: value,
            }
        }));
    };

    render(){
        const { form, error, redirectTo } = this.state;
        if(redirectTo) return <Redirect to={redirectTo}/>;
        return(
            <div className='authForm'>
                <h1>Авторизация</h1>
                <div className='error'>{error}</div>
                <form onSubmit={this.handleSubmit}>
                    <MuiThemeProvider>
                        <TextField
                            hintText="Введите логин"
                            name="login"
                            fullWidth={true}
                            value={form.login}
                            required={true}
                            onChange={this.handleChange}
                        />
                    </MuiThemeProvider>
                    <MuiThemeProvider>
                        <TextField
                            hintText="Введите пароль"
                            type="password"
                            name="password"
                            fullWidth={true}
                            value={form.password}
                            required={true}
                            onChange={this.handleChange}
                        />
                    </MuiThemeProvider>
                    <MuiThemeProvider>
                        <RaiseButtin label="Войти" fullWidth={true} className="authForm-button"> <input type="submit" className="authForm-input" /> </RaiseButtin>
                    </MuiThemeProvider>
                </form>
            </div>
        );
    }
}

export default connect(
    state => ({
        login: state
    }),
    dispatch => ({
        addUser: (user) => {
            dispatch({type: 'ADD_USER', user: user})
        }
    })
)(UserForm)
  • Вопрос задан
  • 288 просмотров
Решения вопроса 1
rockon404
@rockon404
Frontend Developer
Примерно так это можно сделать:

Ваш компонент:
import { login } from './loginDucks';

class UserForm extends Component {
  ...
  handleSubmit = e => {
    this.props.login(this.state.form);
  }
  ...
  render() {
      const { isLoading, isError, shouldRedirect } = this.props;
      if (shouldRedirect) <Redirect to="/index" >;

    return (
      ...
    );
  }
}

const mapStateToProps = state => ({
  isLoading: state.login.isLoading,
  isError: state.login.isError,
  shouldRedirect: state.login.shouldRedirect,
});

const mapDispatchToProps = {
  login,
};

export default connect(mapStateToProps, mapDispatchToProps)(UserForm);


loginDucks.js
const LOGIN_REQUEST = 'LOGIN_REQUEST';
const LOGIN_SUCCESS = 'LOGIN_SUCCESS';
const LOGIN_ERROR = 'LOGIN_ERROR';

const loginSuccess = data => ({
  type: LOGIN_SUCCESS,
  payload: data,
});

const loginError = data => ({
  type: LOGIN_ERROR,
});

export const login = form => async dispatch => {
  try {
    const res = await axios.post('/api/user', form);

    if (!res.data) dispatch(loginError());
    
    dispatch(loginSuccess());
  } catch e {
    dspatch(loginError());
  }
}

const initialState = {
  isLoading: false,
  isError: false,
  shouldRedirect: false,
};

export default (state = initialState, action) => {
  const { type, payload } = action;

  switch(type) {
    case LOGIN_REQUEST:
      return { 
        ...state,
        isLoading: true,
        isError: false,
      };
    case LOGIN_SUCCESS:
      return { 
        ...state,
        isLoading: false,
        shouldRedirect: false,
      };
    case LOGIN_ERROR:
      return  { 
        ...state,
        isLoading: false,
        isError: true,
      };
    default:
      return state;
  }
};


import React from 'react';
import ReactDOM from 'react-dom';
import  { Provider } from 'react-redux';
import { createStore, combineReducers, compose, applyMiddleware } from 'redux';
import thunk from 'redux-thunk';
import { Route, Switch } from 'react-router';
import { BrowserRouter } from 'react-router-dom';
import Auth from './component/AuthForm';
import Helmet from './aplication';
import loginReducer from './loginDucks';

function user(state = {}, action){
    if(action.type === 'ADD_USER'){
        return [
            ...state,
            action.user
        ];
    }
    return state;
}

const rootReducer = combineReducers({
  login: loginReducer,
  user,
});

const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose;

const store = createStore(rootReducer, composeEnhancers(
  applyMiddleware(thunk),
));

ReactDOM.render(
        <div>
            ...
        </div>,
    document.getElementById('content')
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через TM ID
Похожие вопросы