【问题标题】:unable to bind actions to component React Redux无法将操作绑定到组件 React Redux
【发布时间】:2020-06-04 16:37:03
【问题描述】:

我无法将动作绑定到这个组件,我正在使用 redux 来绑定动作,组件的状态我越来越不确定,请帮助我提前谢谢。

我下面添加的actions和store和reducer是组件,Action,reducer

        import React from 'react';
        import { Formik, Field, Form, ErrorMessage } from 'formik';
        import { bindActionCreators } from 'redux'
        import * as Yup from 'yup';
        import { connect } from "react-redux";
        import * as Actions from '../_actions'


        //import { userActions } from '../_actions';

        import { authenticationService } from '../_services';


        export class LoginPage extends React.Component {

            constructor(props) {

                super(props);

                // redirect to home if already logged in
                if (authenticationService.currentUserValue) {
                    this.props.history.push('/');
                }
            }

            render() {
                return (
                    <div>
                        <div className="alert alert-info">
                            <strong>Normal User</strong> - U: user P: user<br />
                            <strong>Administrator</strong> - U: admin P: admin
                        </div>
                        <h2>Login</h2>
                        <Formik
                            initialValues={{
                                username: '',
                                password: ''
                            }}
                            validationSchema={Yup.object().shape({
                                username: Yup.string().required('Username is required'),
                                password: Yup.string().required('Password is required')
                            })}
                            onSubmit={((obj) => this.props.Actions.login(obj.username, obj.password))}

                            render={({ errors, status, touched, isSubmitting }) => (
                                <Form>
                                    <div className="form-group">
                                        <label htmlFor="username">Username</label>
                                        <Field name="username" type="text" className={'form-control' + (errors.username && touched.username ? ' is-invalid' : '')} />
                                        <ErrorMessage name="username" component="div" className="invalid-feedback" />
                                    </div>
                                    <div className="form-group">
                                        <label htmlFor="password">Password</label>
                                        <Field name="password" type="password" className={'form-control' + (errors.password && touched.password ? ' is-invalid' : '')} />
                                        <ErrorMessage name="password" component="div" className="invalid-feedback" />
                                    </div>
                                    <div className="form-group">
                                        <button type="submit" className="btn btn-primary" disabled={isSubmitting}>Login</button>
                                        {isSubmitting &&
                                            <img src="data:image/gif;base64,R0lGODlhEAAQAPIAAP///wAAAMLCwkJCQgAAAGJiYoKCgpKSkiH/C05FVFNDQVBFMi4wAwEAAAAh/hpDcmVhdGVkIHdpdGggYWpheGxvYWQuaW5mbwAh+QQJCgAAACwAAAAAEAAQAAADMwi63P4wyklrE2MIOggZnAdOmGYJRbExwroUmcG2LmDEwnHQLVsYOd2mBzkYDAdKa+dIAAAh+QQJCgAAACwAAAAAEAAQAAADNAi63P5OjCEgG4QMu7DmikRxQlFUYDEZIGBMRVsaqHwctXXf7WEYB4Ag1xjihkMZsiUkKhIAIfkECQoAAAAsAAAAABAAEAAAAzYIujIjK8pByJDMlFYvBoVjHA70GU7xSUJhmKtwHPAKzLO9HMaoKwJZ7Rf8AYPDDzKpZBqfvwQAIfkECQoAAAAsAAAAABAAEAAAAzMIumIlK8oyhpHsnFZfhYumCYUhDAQxRIdhHBGqRoKw0R8DYlJd8z0fMDgsGo/IpHI5TAAAIfkECQoAAAAsAAAAABAAEAAAAzIIunInK0rnZBTwGPNMgQwmdsNgXGJUlIWEuR5oWUIpz8pAEAMe6TwfwyYsGo/IpFKSAAAh+QQJCgAAACwAAAAAEAAQAAADMwi6IMKQORfjdOe82p4wGccc4CEuQradylesojEMBgsUc2G7sDX3lQGBMLAJibufbSlKAAAh+QQJCgAAACwAAAAAEAAQAAADMgi63P7wCRHZnFVdmgHu2nFwlWCI3WGc3TSWhUFGxTAUkGCbtgENBMJAEJsxgMLWzpEAACH5BAkKAAAALAAAAAAQABAAAAMyCLrc/jDKSatlQtScKdceCAjDII7HcQ4EMTCpyrCuUBjCYRgHVtqlAiB1YhiCnlsRkAAAOwAAAAAAAAAAAA=="
                                                alt="login" />
                                        }
                                    </div>
                                    {status &&
                                        <div className={'alert alert-danger'}>{status}</div>
                                    }
                                </Form>
                            )}
                        />
                    </div>
                )
            }
        }
        function mapDispatch(dispatch) {
            return bindActionCreators({ Actions }, dispatch)
        }
        function mapStateProps(props) {
            return {
                allprop: props
            }
        }

        connect(mapStateProps, mapDispatch)(LoginPage); 

action 我有 index.js 文件,所以我要添加 action 主代码

    import { authenticationConstants } from '../_constants';
    import { authenticationService } from '../_services';
    import { history } from '../_helpers';
    import{alertActions} from './alert.actions'

    export const userActions = {
        login,
        logout,
        getAll,
    };

    function login(username, password) {
        return dispatch => {
            dispatch(request({ username }));

            authenticationService.login(username, password)
                .then(
                    user => { 
                        dispatch(success(user));
                        history.push('/');
                    },
                    error => {
                        dispatch(failure(error));
                        dispatch(alertActions.error(error));
                    }
                );
        };

        function request(user) { return { type: authenticationConstants.LOGIN_REQUEST, user } }
        function success(user) { return { type: authenticationConstants.LOGIN_SUCCESS, user } }
        function failure(error) { return { type: authenticationConstants.LOGIN_FAILURE, error } }
    }

    function logout() {
        authenticationService.logout();
        return { type: authenticationConstants.LOGOUT };
    }

    function getAll() {
        return dispatch => {
            dispatch(request());

            authenticationService.getAll()
                .then(
                    users => dispatch(success(users)),
                    error => dispatch(failure(error))
                );
        };

        function request() { return { type: authenticationConstants.GETALL_REQUEST } }
        function success(users) { return { type: authenticationConstants.GETALL_SUCCESS, users } }
        function failure(error) { return { type: authenticationConstants.GETALL_FAILURE, error } }
    }

我正在添加reducer,请通过它

import { authenticationConstants } from '../_constants';

let user = JSON.parse(localStorage.getItem('user'));
const initialState = user ? { loggedIn: true, user } : {};

export function authentication(state = initialState, action) {
  switch (action.type) {
    case authenticationConstants.LOGIN_REQUEST:
      return {
        loggingIn: true,
        user: action.user
      };
    case authenticationConstants.LOGIN_SUCCESS:
      return {
        loggedIn: true,
        user: action.user
      };
    case authenticationConstants.LOGIN_FAILURE:
      return {};
    case authenticationConstants.LOGOUT:
      return {};
    case authenticationConstants.GETALL_REQUEST:
      return {
        loading: true
      };
    case authenticationConstants.GETALL_SUCCESS:
      return {
        items: action.users
      };
    case authenticationConstants.GETALL_FAILURE:
      return {
        error: action.error
      };
    default:
      return state
  }
}

【问题讨论】:

  • connect HOC 的第二个参数将为您绑定 dispatch 到您的动作创建者。尝试简化您的 mapDispatch 代码,看看它是否会自行解决。

标签: reactjs redux react-redux


【解决方案1】:

您必须将 Actions 作为第一个参数传递给 bindActionCreators 而不是作为对象

 function mapDispatch(dispatch) {
        return bindActionCreators(Actions, dispatch)
 }

然后使用类似的动作

this.props.login(obj.username, obj.password);

但是,您可以简单地将对象用作第二个参数,而不是使用 bindActionCreators 之类的

connect(mapStateProps, Actions)(LoginPage);

另外你必须导出并使用连接的组件,而不是导出普通的组件

所以不是这个

export class LoginPage extends React.Component {

你应该有

class LoginPage extends React.Component {
....

const LoginPageWithConnect = connect(mapStateProps, Actions)(LoginPage);
export { LoginPageWithConnect as LoginPage };

【讨论】:

  • 非常感谢,但我仍然得到相同的响应,动作没有绑定到组件,上面我们没有绑定“mapDispatch”我们直接绑定动作
  • connect 的第二个参数也采用普通对象。确保正确导出组件
  • reducer,绑定到 props 但作为空对象 alert: {} authentication: {} proto: Object
  • 我无法理解你的意思
猜你喜欢
  • 2016-09-06
  • 2018-08-28
  • 2019-01-04
  • 2018-11-03
  • 2020-02-25
  • 2018-04-08
  • 2016-06-06
  • 2018-04-22
  • 1970-01-01
相关资源
最近更新 更多