微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

我无法让Redux动作正常工作,我无法发现某些错误,请咨询

如何解决我无法让Redux动作正常工作,我无法发现某些错误,请咨询

我找不到我做错了什么,但是导入了action saveUser,而mapdispatchToProps看起来像是链接action正确的链接,但仍然出现此错误>

enter image description here

(此代码之后为action代码

mapdispatchToProps正在链接action saveUser,如果我按住CTRL键单击它,则VSCode跳转到Action,如下所示:
那么为什么出现错误“ TypeError:saveUser不是函数

enter image description here

在类LinkAccounts.jsx中,该类具有mapdispatchToProps

/* eslint-disable max-classes-per-file */
import React,{ Component } from 'react';
import { connect } from 'react-redux';
import { compose } from 'recompose';
import { AuthUserContext,withAuthorization } from '../../session';
import { withFirebase } from '../../firebase';
import { SIGN_IN_METHODS } from '../../constants/signinmethods';
import * as ROLES from '../../constants/roles';
import '../../styles/link-account.scss';
import asyncSaveUser from '../../redux/userData/user.actions';

class LoginManagementBase extends Component {
    constructor() {
        super();
        this.state = {
            activeSignInMethods: [],anonymousSignIn: null,error: null,};
    }

    componentDidMount() {
        this.fetchSignInMethods();
    }

    fetchSignInMethods = () => {
        const { firebase,authUser } = this.props;
        const email = authUser.email === null ? 'none@guest.ac' : authUser.email;
        firebase.auth
            .fetchSignInMethodsForEmail(email)
            .then(activeSignInMethods =>
                this.setState({
                    activeSignInMethods,anonymousSignIn: activeSignInMethods.length === 0,}),)
            .catch(error => this.setState({ error }));
    };

    onSocialLoginLink = provider => {
        const { firebase,saveUser } = this.props;
        firebase.auth.currentUser
            .linkWithPopup(firebase[provider])
            // .linkWithRedirect(this.props.firebase[provider])
            .then(saveUser())
            .then(this.fetchSignInMethods)
            .catch(error => this.setState({ error }));
    };

    onDefaultLoginLink = password => {
        const { firebase,authUser } = this.props;
        const credential = firebase.emailAuthProvider.credential(authUser.email,password);

        firebase.auth.currentUser
            .linkAndRetrieveDataWithCredential(credential)
            .then(this.fetchSignInMethods)
            .catch(error => this.setState({ error }));
    };

    onUnlink = providerId => {
        const { firebase } = this.props;
        firebase.auth.currentUser
            .unlink(providerId)
            .then(this.fetchSignInMethods)
            .catch(error => this.setState({ error }));
    };

    render() {
        const { activeSignInMethods,anonymousSignIn,error } = this.state;
        console.log('Debug: ',activeSignInMethods.length);
        return (
            <div className="providetoggler">
                &nbsp;&nbsp;&nbsp;
                <h1>
                    You are signed in Anonymously changes you do is only saved in this browser. If you want to access your
                    progress anywhere please sign in below!
                </h1>
                &nbsp;
                <ul>
                    {SIGN_IN_METHODS.map(signInMethod => {
                        const onlyOneLeft = activeSignInMethods.length === 1;
                        const isEnabled = activeSignInMethods.includes(signInMethod.id);

                        return (
                            <li key={signInMethod.id}>
                                {signInMethod.id === 'password' ? (
                                    <DefaultLoginToggle
                                        // accountEmail={this.props.authUser.email}
                                        onlyOneLeft={onlyOneLeft}
                                        isEnabled={isEnabled}
                                        signInMethod={signInMethod}
                                        onLink={this.onDefaultLoginLink}
                                        onUnlink={this.onUnlink}
                                    />
                                ) : (
                                    <SocialLoginToggle
                                        onlyOneLeft={onlyOneLeft}
                                        isEnabled={isEnabled}
                                        signInMethod={signInMethod}
                                        onLink={this.onSocialLoginLink}
                                        onUnlink={this.onUnlink}
                                    />
                                )}
                            </li>
                        );
                    })}
                </ul>
                {error && error.message}
            </div>
        );
    }
}

const SocialLoginToggle = ({ onlyOneLeft,isEnabled,signInMethod,onLink,onUnlink }) =>
    isEnabled ? (
        <button type="button" onClick={() => onUnlink(signInMethod.id)} disabled={onlyOneLeft}>
            Unlink <i className={signInMethod.icon} aria-hidden="true" /> {signInMethod.name} sign in
        </button>
    ) : (
        <button type="button" onClick={() => onLink(signInMethod.provider)}>
            Link <i className={signInMethod.icon} aria-hidden="true" /> {signInMethod.name} sign in
        </button>
    );

class DefaultLoginToggle extends Component {
    constructor() {
        super();
        this.state = { passwordOne: '',passwordTwo: '' };
    }

    onSubmit = event => {
        const { passwordOne } = this.state;
        const { onLink } = this.props;
        event.preventDefault();
        onLink(passwordOne);
        this.setState({ passwordOne: '',passwordTwo: '' });
    };

    onChange = event => {
        this.setState({ [event.target.name]: event.target.value });
    };

    render() {
        const { signInMethod } = this.props;
        const { passwordOne,passwordTwo } = this.state;
        const isInvalid = passwordOne !== passwordTwo || passwordOne === '';
        return (
            <form onSubmit={this.onSubmit}>
                Link <i className={signInMethod.icon} aria-hidden="true" /> {signInMethod.name} sign in
                <input
                    name="passwordOne"
                    value={passwordOne}
                    onChange={this.onChange}
                    type="password"
                    placeholder="Password for email sign in"
                />
                <input
                    name="passwordTwo"
                    value={passwordTwo}
                    onChange={this.onChange}
                    type="password"
                    placeholder="Confirm New Password"
                />
                <button disabled={isInvalid} type="submit">
                    Save password for email sign in
                </button>
            </form>
        );
    }
}

const LinkAccounts = () => (
    <AuthUserContext.Consumer>
        {authUser => (
            <div>
                <LoginManagement authUser={authUser} />
            </div>
        )}
    </AuthUserContext.Consumer>
);

const mapdispatchToProps = dispatch => ({
    saveUser: () => dispatch(asyncSaveUser()),});

const LoginManagement = withFirebase(LoginManagementBase);
const condition = authUser => authUser && authUser.roles.includes(ROLES.ANON);

const enhance = compose(withAuthorization(condition),connect(null,mapdispatchToProps));

export default enhance(LinkAccounts);

这是user.actions.js文件中的操作:

import { userActionTypes } from './user.types';
import { withFirebase } from '../../firebase';
import * as ROLES from '../../constants/roles';

const saveUserStart = () => ({
    type: userActionTypes.SAVE_USER_START,});

const saveUserSuccess = user => ({
    type: userActionTypes.SAVE_USER_SUCCESS,payload: user,});

const saveUserFailure = errMsg => ({
    type: userActionTypes.SAVE_USER_FAILURE,payload: errMsg,});

const asyncSaveUser = ({ firestore }) => {
    return async dispatch => {
        const userRef = firestore.userDoc(firestore.auth.currentUser.uid);
        dispatch(saveUserStart());
        firestore.db
            .runTransaction(transaction => {
                // This code may get re-run multiple times if there are conflicts.
                return transaction.get(userRef).then(doc => {
                    if (!doc.exists) {
                        return Promise.reject('Transaction Failed: User dont exist!');
                    }
                    const newRoles = doc.data().roles;
                    // new roll
                    newRoles.push(ROLES.USER);
                    // remove roll
                    newRoles.splice(newRoles.indexOf('ANONYMOUS'),1);
                    // save it back
                    transaction.update(userRef,{ roles: newRoles });
                    return newRoles;
                });
            })
            .then(newRoles => {
                dispatch(saveUserSuccess());
                console.log(`Transaction successfully committed role(s): ${newRoles}`);
            })
            .catch(error => {
                dispatch(saveUserFailure(error));
                console.log(error);
            });
    };
};

export default withFirebase(asyncSaveUser);

解决方法

saveUser不会作为prop在LoginManagementBase组件中传递。

仅作为enhance的{​​{1}}作为道具传递。

我认为您想改写LinkAccounts

LoginManagement

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。