@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)
  • Вопрос задан
  • 128 просмотров
Решения вопроса 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
Похожие вопросы