Reactjs TypeError:this.props.setLoginDisabled不是函数

Reactjs TypeError:this.props.setLoginDisabled不是函数,reactjs,react-native,react-redux,Reactjs,React Native,React Redux,有一个名为Login的屏幕,它从loginActions传入一个动作创建者,如下所示: 启动应用程序并单击登录按钮时,出现以下错误: 在应用程序的旧版本中,所有这些都正常工作,没有这样的错误,但是现在在升级的0.60.4版本中单击登录按钮时,我得到了这个错误 当我查看loginActions文件时,我想知道是否应该有一个export default connect()()和mapDispatchToProps,将道具插入Login屏幕。所以我的一个问题是,我真的需要这个吗 它以前是怎么工作的

有一个名为
Login
的屏幕,它从
loginActions
传入一个动作创建者,如下所示:

启动应用程序并单击登录按钮时,出现以下错误:

在应用程序的旧版本中,所有这些都正常工作,没有这样的错误,但是现在在升级的0.60.4版本中单击登录按钮时,我得到了这个错误

当我查看
loginActions
文件时,我想知道是否应该有一个
export default connect()()
mapDispatchToProps
,将道具插入
Login
屏幕。所以我的一个问题是,我真的需要这个吗

它以前是怎么工作的?是父母传下来的吗?这是
loginActions.js
文件:

import {Alert} from 'react-native';
import logger from 'logger';
import * as types from 'auth/constants';
import * as endpoints from 'endpoints';
import * as cache from 'utils/cache';
import {AUTH_STATUS} from 'enums/authStatus';
import * as requester from 'services/Requester';
import {clearSurveys} from 'surveys-ballots/actions';
import {clearEvents} from 'events/actions';
import * as repsActions from 'representatives/actions';
import {clearRegistration} from 'auth/registrationActions';
import {clearFeed} from 'activity-feed/actions';
import {clearActionAlerts} from 'action-alerts/actions';
import * as dataHelpers from 'auth/helpers/data-helpers';
import * as helpers from 'auth/helpers/actions-helpers';
import {verificationEmailChanged} from 'auth/registrationActions';
import {clearMembershipFields} from 'membership/actions';
import {
  setRelevantStates,
  clearPreferences,
} from 'account-settings/preferencesActions';
import {fetchPrefences, fetchTopics} from 'account-settings/preferencesActions';
import * as appcenter from 'utils/appcenterLogger';

export function setAuthStatus(authStatus) {
  return async (dispatch, getState) => {
    try {
      const {auth: {user}} = getState();
      dispatch({
        type: types.SET_AUTH_STATUS,
        payload: {
          ...user,
          authStatus,
        },
      });
      logger(types.SET_AUTH_STATUS);
    } catch (error) {
      logger('error in setAuthStatus');
      return false;
    }
  };
}

export function handleLogin({email, password, rememberEmail}) {
  return async dispatch => {
    try {
      dispatch({type: types.LOGIN_STARTED});
      logger(types.LOGIN_STARTED);

      const response = await requester.sendPost(endpoints.USER_LOGIN, {
        Username: email,
        Password: password,
      });

      const needsSetup = dataHelpers.needsSetup(response);

      if (needsSetup) {
        dispatch({
          type: types.EMAIL_VERIFICATION_SUBMIT_ENDED_SUCCESS,
          payload: response,
        });
        dispatch(verificationEmailChanged(email));
        return Promise.resolve({
          needsSetup: true,
        });
      }
      const user = {
        ...response,
        authStatus: AUTH_STATUS.LOGGED_IN,
      };

      cache.saveUserRef(user);
      cache.handleEmailCache(email, rememberEmail);

      helpers.sendOneSignalTags(user, true);
      appcenter.trackUser('UserLogin', user, true);

      dispatch({
        type: types.LOGIN_SUCCESS,
        payload: user,
      });

      const deepLinkedEvent = await cache.getDeepLinkedElement('event');
      const deepLinkedBallot = await cache.getDeepLinkedElement('survey');

      dispatchAfterLoginActions(dispatch, user);

      logger(types.LOGIN_SUCCESS);

      return Promise.resolve({
        needsSetup: false,
        deepLinkedEvent,
        deepLinkedBallot,
      });
    } catch (e) {
      logger(types.LOGIN_ERROR, e);
      const error = e && e.Message;
      dispatch({type: types.LOGIN_ERROR, payload: error});
    }
  };
}

export function checkSession(responseError) {
  return (dispatch, getState) => {
    const {auth: {user}} = getState();
    if (
      user.authStatus === AUTH_STATUS.LOGGED_IN &&
      responseError &&
      responseError.Message &&
      (responseError.Message.lastIndexOf('TokenExpired') >= 0 ||
        responseError.Message === 'Individual not found')
    ) {
      dispatch(handleLogout());
      return Alert.alert(
        'Session Timeout',
        'For your security, your NFIB session has timed out due to inactivity.',
        [{text: 'Ok', onPress: () => false}]
      );
    }
  };
}

export function handleLogout() {
  return async (dispatch, getState) => {
    const {auth: {user}} = getState();

    dispatch(clearSurveys());
    dispatch(clearEvents());
    dispatch(clearRegistration());
    dispatch(repsActions.clearRepresentatives());
    dispatch(clearFeed());
    dispatch(clearActionAlerts());
    dispatch(clearMembershipFields());
    dispatch(clearPreferences());
    dispatch({type: types.RESET_LOGIN_STATE});

    cache.clearCache();
    helpers.sendOneSignalTags(user, false);
    appcenter.trackUser('UserLogout', user, false);
    requester.resetTokenExpired();
  };
}

export function setCurrentUser({Key}) {
  return async dispatch => {
    try {
      dispatch({type: types.FETCH_USER_DETAILS_STARTED});
      const user = await helpers.fetchCurrentUserDetails(Key);
      dispatch({
        type: types.SET_CURRENT_USER,
        payload: {
          ...user,
          authStatus: AUTH_STATUS.LOGGED_IN,
        },
      });

      dispatchAfterLoginActions(dispatch, user);

      logger(types.SET_CURRENT_USER);
    } catch (error) {
      dispatch({
        type: types.FETCH_USER_DETAILS_FINISHED_ERROR,
        payload: error,
      });
      dispatch(checkSession(error));
      logger(types.FETCH_USER_DETAILS_FINISHED_ERROR);
    }
  };
}

function dispatchAfterLoginActions(dispatch, user) {
  dispatch(fetchUserOrganizationDetails(user));
  dispatch(validateUserInformationForVoterVoice());
  dispatch(setRelevantStates());
  dispatch(fetchPrefences(user));
  dispatch(fetchTopics());
}

export function setUserMembership(user) {
  const isMember = Boolean(user.Organization && user.Organization.Key);
  return {
    type: types.SET_USER_MEMBERSHIP,
    payload: isMember,
  };
}

export function fetchUserOrganizationDetails(user) {
  return async dispatch => {
    try {
      if (user.Organization && user.Organization.Key) {
        const {Key} = user.Organization;
        const payload = await helpers.fetchOrganizationDetails(Key);
        dispatch({
          type: types.GET_USER_ORGANIZATION_FINISHED_SUCCESS,
          payload,
        });
        dispatch(setUserMembership(user));
        logger(types.GET_USER_ORGANIZATION_FINISHED_SUCCESS);
        helpers.sendOneSignalOrganizationTags(payload);
        cache.saveOrganizationData(payload);
      }
    } catch (error) {
      logger(types.GET_USER_ORGANIZATION_FINISHED_ERROR);
      dispatch({
        type: types.GET_USER_ORGANIZATION_FINISHED_ERROR,
        payload: error,
      });
      dispatch(checkSession(error));
    }
  };
}

export function setUserPosition(coords) {
  return {
    type: types.SET_USER_POSITION,
    payload: coords,
  };
}

export function setEmailField(email) {
  return {
    type: types.SET_EMAIL_FIELD,
    payload: email,
  };
}

export function setPasswordField(password) {
  return {
    type: types.SET_PASSWORD_FIELD,
    payload: password,
  };
}

export function setSecurityTextEntry(current) {
  return {
    type: types.SET_SECURITY_TEXT_ENTRY,
    payload: current,
  };
}

export function setLoginDisabled(status) {
  return {
    type: types.SET_LOGIN_DISABLED,
    payload: status,
  };
}

export function validateUserAddress() {
  return async (dispatch, getState) => {
    try {
      logger(types.VALIDATE_USER_ADDRESS_STARTED);
      dispatch({type: types.VALIDATE_USER_ADDRESS_STARTED});
      const {auth: {user: {PersonalAddress}}} = getState();
      const payload = await helpers.validateAddress({
        homeAddress: PersonalAddress.AddressLine1,
        city: PersonalAddress.City,
        state: PersonalAddress.StateCode,
        zipCode: PersonalAddress.PostalCode,
      });
      dispatch({type: types.VALIDATE_USER_ADDRESS_SUCCESS, payload});
      logger(types.VALIDATE_USER_ADDRESS_SUCCESS);
    } catch (error) {
      logger(types.VALIDATE_USER_ADDRESS_ERROR);
      dispatch({
        type: types.VALIDATE_USER_ADDRESS_ERROR,
        payload: error,
      });
      dispatch(checkSession(error));
    }
  };
}

export function validateUserInformationForVoterVoice(userKey = null) {
  return async (dispatch, getState) => {
    try {
      logger(types.VALIDATE_USER_INFORMATION_FOR_VOTER_VOICE_STARTED);
      dispatch({
        type: types.VALIDATE_USER_INFORMATION_FOR_VOTER_VOICE_STARTED,
      });

      const {auth: {user: {Key}}} = getState();
      const payload = await helpers.validateUserInformationForVoterVoice(
        userKey || Key
      );

      logger(types.VALIDATE_USER_INFORMATION_FOR_VOTER_VOICE_SUCCESS);
      dispatch({
        type: types.VALIDATE_USER_INFORMATION_FOR_VOTER_VOICE_SUCCESS,
        payload,
      });
    } catch (error) {
      dispatch({
        type: types.VALIDATE_USER_INFORMATION_FOR_VOTER_VOICE_ERROR,
        payload: error,
      });
    }
  };
}

export function sendVerificationEmail() {
  return async (dispatch, getState) => {
    try {
      logger(types.SEND_EMAIL_CONFIRMATION_STARTED);
      dispatch({type: types.SEND_EMAIL_CONFIRMATION_STARTED});

      const {auth: {user: {Key}}} = getState();
      const payload = await helpers.sendVerificationEmail(Key);

      logger(types.SEND_EMAIL_CONFIRMATION_SUCCESS);
      dispatch({
        type: types.SEND_EMAIL_CONFIRMATION_SUCCESS,
        payload,
      });
    } catch (error) {
      dispatch({
        type: types.SEND_EMAIL_CONFIRMATION_ERROR,
        payload: error,
      });
    }
  };
}

export function toggleRememberEmail() {
  return {type: types.TOGGLE_REMEMBER_EMAIL};
}
这是减速器:

import {AUTH_STATUS} from 'enums/authStatus';
import * as types from 'auth/constants';

export const INITIAL_STATE = {
  user: {
    authStatus: AUTH_STATUS.LOGGED_OUT,
  },
  error: null,
  loading: false,
  isMember: false,
  userOrganization: null,
  primaryIndividual: null,
  userPosition: null,
  email: '',
  password: '',
  useSecureTextEntry: true,
  isDisabled: false,
  validatingUserAddress: true,
  validatingUserAddressForVV: true,
  userAddressValid: true,
  userAddressIsValidForVoterVoice: false,
  userEmailIsValidForVoterVoice: false,
  rememberEmail: true,
};

//eslint-disable-next-line
export default (state = INITIAL_STATE, {type, payload}) => {
  switch (type) {
    case types.LOGIN_STARTED:
      return {...state, loading: true, error: null};
    case types.LOGIN_SUCCESS:
      return {...state, user: payload, loading: false};
    case types.LOGIN_ERROR:
      return {
        ...state,
        loading: false,
        error: payload,
      };
    case types.EMAIL_VERIFICATION_SUBMIT_ENDED_SUCCESS:
      return {...state, loading: false};
    case types.SET_CURRENT_USER:
      return {...state, loading: false, user: payload};
    case types.SET_AUTH_STATUS:
      return {...state, user: payload};
    case types.SET_USER_MEMBERSHIP:
      return {...state, isMember: payload};
    case types.GET_USER_ORGANIZATION_STARTED:
      return {...state, loading: true, error: null};
    case types.GET_USER_ORGANIZATION_FINISHED_SUCCESS:
      return {...state, loading: false, ...payload};
    case types.GET_USER_ORGANIZATION_FINISHED_ERROR:
      return {...state, loading: false, error: payload};
    case types.RESET_LOGIN_STATE:
      return INITIAL_STATE;
    case types.SET_USER_POSITION:
      return {...state, userPosition: payload};
    case types.FETCH_USER_DETAILS_STARTED:
      return {...state, loading: true, error: null};
    case types.FETCH_USER_DETAILS_FINISHED_ERROR:
      return {...state, loading: false, error: payload};
    case types.SET_EMAIL_FIELD:
      return {...state, email: payload};
    case types.SET_PASSWORD_FIELD:
      return {...state, password: payload};
    case types.SET_SECURITY_TEXT_ENTRY:
      return {...state, useSecureTextEntry: payload};
    case types.SEND_EMAIL_CONFIRMATION_STARTED:
      return {...state, loading: true};
    case types.SEND_EMAIL_CONFIRMATION_SUCCESS:
      return {...state, loading: false};
    case types.SEND_EMAIL_CONFIRMATION_ERROR:
      return {...state, loading: false};
    case types.SET_LOGIN_DISABLED:
      return {...state, isDisabled: payload};
    case types.UPDATE_PERSONAL_DETAILS:
      return {
        ...state,
        user: {
          ...state.user,
          PersonalDetails: payload,
        },
      };
    case types.UPDATE_CONTACT_DETAILS:
      return {
        ...state,
        user: {
          ...state.user,
          ContactDetails: payload,
        },
      };
    case types.UPDATE_PERSONAL_ADDRESS:
      return {
        ...state,
        user: {
          ...state.user,
          PersonalAddress: payload,
        },
      };
    case types.VALIDATE_USER_ADDRESS_STARTED:
      return {...state, validatingUserAddress: true};
    case types.VALIDATE_USER_ADDRESS_SUCCESS:
      return {
        ...state,
        validatingUserAddress: false,
        userAddressValid: payload,
      };
    case types.VALIDATE_USER_ADDRESS_ERROR:
      return {...state, validatingUserAddress: false};
    case types.VALIDATE_USER_INFORMATION_FOR_VOTER_VOICE_STARTED:
      return {...state, validatingUserAddressForVV: true};
    case types.VALIDATE_USER_INFORMATION_FOR_VOTER_VOICE_SUCCESS: {
      const {
        userAddressIsValidForVoterVoice,
        userEmailIsValidForVoterVoice,
      } = payload;
      return {
        ...state,
        userAddressIsValidForVoterVoice,
        userEmailIsValidForVoterVoice,
        validatingUserAddressForVV: false,
      };
    }
    case types.VALIDATE_USER_INFORMATION_FOR_VOTER_VOICE_ERROR:
      return {
        ...state,
        userAddressIsValidForVoterVoice: false,
        userEmailIsValidForVoterVoice: false,
        validatingUserAddressForVV: false,
      };
    case types.TOGGLE_REMEMBER_EMAIL:
      return {...state, rememberEmail: !state.rememberEmail};
    default:
      return state;
  }
};
这都在
src/auth
的内部

Login
屏幕正在
src/navigation/auth/stack.js的内部使用:

import React from "react";
import { StackNavigator, NavigationActions } from "react-navigation";
import { Intro } from "auth/screens/Intro";
import { Login } from "auth/screens/Login";
import { PasswordReset } from "auth/screens/PasswordReset";
import { RegisterNoEmail } from "auth/screens/RegisterNoEmail";
import AskForMembership from "auth/screens/AskForMembership";
import { CompleteAccount } from "auth/screens/CompleteAccount";
import { ConfirmMemberAccount } from "auth/screens/ConfirmMemberAccount";
import { Register } from "auth/screens/Register";
import { SetNewPassword } from "auth/screens/SetNewPassword";
import { RegisterEmailPassword } from "auth/screens/RegisterEmailPassword";
import { ResetLinkConfirmationAlert } from "auth/screens/ResetLinkConfirmationAlert";
import { DetailsConfirmation } from "auth/screens/DetailsConfirmation";
import { AccountCreated } from "auth/screens/AccountCreated";

import BackButton from "navigation-components/BackButton";
import CustomHeader from "navigation-components/CustomHeader";
import HeaderTitle from "navigation-components/HeaderTitle";
import { v2Colors } from "theme";
import { defaultStackConfig, defaultHeaderStyles } from "../config";

const leftRegiterNavOptions = {
  title: "Register",
  headerStyle: defaultStackConfig.authHeaderStyle
};

const stack = StackNavigator(
  {
    Intro: {
      screen: Intro,
      navigationOptions: {
        header: null
      }
    },
    Register: {
      screen: Register,
      navigationOptions: ({ navigation }) => ({
        header: <CustomHeader onPress={() => navigation.goBack(null)} />,
        headerStyle: defaultStackConfig.authHeaderStyle
      })
    },
    RegisterNoEmail: {
      screen: RegisterNoEmail,
      navigationOptions: leftRegiterNavOptions
    },
    RegisterEmailPassword: {
      screen: RegisterEmailPassword,
      navigationOptions: leftRegiterNavOptions
    },
    AskForMembership: {
      screen: AskForMembership,
      navigationOptions: {
        header: <HeaderTitle />,
        headerStyle: defaultStackConfig.authHeaderStyle
      }
    },
    ConfirmMemberAccount: {
      screen: ConfirmMemberAccount,
      navigationOptions: ({ navigation }) => ({
        header: (
          <HeaderTitle
            headerLeft={() => (
              <BackButton onPress={() => navigation.goBack(null)} />
            )}
          />
        ),
        headerStyle: defaultStackConfig.authHeaderStyle
      })
    },
    CompleteAccount: {
      screen: CompleteAccount,
      navigationOptions: {
        header: <HeaderTitle />,
        headerStyle: defaultStackConfig.authHeaderStyle
      }
    },
    Login: {
      screen: Login,
      navigationOptions: ({ navigation }) => ({
        title: "Log In",
        headerLeft: <BackButton onPress={() => navigation.goBack(null)} />,
        headerStyle: defaultStackConfig.authHeaderStyle
      })
    },
/* eslint react/forbid-prop-types: "off"*/
import React from "react";
import {
  View,
  Image,
  Keyboard,
  TouchableWithoutFeedback,
  Text
} from "react-native";
import PropTypes from "prop-types";
import { connect } from "react-redux";
import { TextButton } from "react-native-material-buttons";
import { colors, v2ButtonStyles, v2Colors } from "theme";
import { Loading } from "common-components";
import { setAuthStatus } from "auth/loginActions";
import styles from "auth/styles";

const logo = require("icons/NFIB_white.png");

const propTypes = {
  loading: PropTypes.bool,
  navigation: PropTypes.object.isRequired,
  setAuthStatus: PropTypes.func.isRequired
};

export class Intro extends React.Component {
  _dismiss = () => {
    Keyboard.dismiss();
  };

  render() {
    return (
      <View style={styles.container}>
        <TouchableWithoutFeedback onPress={this._dismiss}>
          <View style={{ flex: 1 }} accessible={true}>
            <Image
              source={logo}
              style={styles.v2Logo}
              accessible={true}
              accessibilityLabel={"imgLogo"}
            />
            {this.props.loading && <Loading />}
            {!this.props.loading && (
              <View style={styles.footerWrapper}>
                <View style={styles.authButtonsWrapper} accessible={true}>
                  <TextButton
                    color={v2Colors.green}
                    title={"LOG IN"}
                    titleColor={colors.white}
                    onPress={() => this.props.navigation.navigate("Login")}
                    style={styles.authButton}
                    titleStyle={v2ButtonStyles.titleStyle}
                    accessibilityLabel={"btnLogin"}
                    accessibilityTraits={"button"}
                    accessibilityComponentType={"button"}
                  />
                  <Text style={styles.textSeparatorNewLine} />
                  <Text style={styles.textSeparatorNewLine}>
                    {" "}
                    {"First time here?"}
                  </Text>
                  <TextButton
                    color={v2Colors.green}
                    title={"REGISTER"}
                    titleColor={colors.white}
                    onPress={() => this.props.navigation.navigate("Register")}
                    style={styles.authButton}
                    titleStyle={v2ButtonStyles.titleStyle}
                    accessibilityLabel={"btnRegister"}
                    accessibilityTraits={"button"}
                    accessibilityComponentType={"button"}
                  />
                </View>
              </View>
            )}
          </View>
        </TouchableWithoutFeedback>
      </View>
    );
  }
}

Intro.propTypes = propTypes;
const mapState2Props = ({ auth }) => {
  const { loading } = auth;
  return { loading };
};

export default connect(
  mapState2Props,
  {
    setAuthStatus
  }
)(Intro);
setLoginDisabled
未被调度:

export function setLoginDisabled(status) {
  return {
    type: types.SET_LOGIN_DISABLED,
    payload: status
  };
}
所以我尝试
dispatch
it,就像这样:

export const setLoginDisabled = status => async (dispatch, getState) => {
  dispatch({ type: types.SET_LOGIN_DISABLED, payload: status });
};
仍然得到了与上面相同的错误。我不认为这有什么区别

因此,我决定在其import语句之后立即使用
console.log(setLoginDisabled)
,得到:

ƒ setLoginDisabled(status) {
    return {
      type: types.SET_LOGIN_DISABLED,
      payload: status
    };
  }
因此,在导入时,它肯定会被定义。然后我试着:

// all this logic below will need to be consolidated into one `componentDidMount()`
  UNSAFE_componentWillMount() {
    console.log(this.props.setLoginDisabled);
    this.props.setLoginDisabled();
    this.keyboardDidShowListener = Keyboard.addListener(
      "keyboardDidShow",
      this._keyboardDidShow
    );
    this.keyboardDidHideListener = Keyboard.addListener(
      "keyboardDidHide",
      this._keyboardDidHide
    );
  }
而且我没有得到任何回报

我开始认为问题可能与
要求周期
有关,因为我收到很多警告,说
登录
中的许多动作创建者未定义,我也收到这些警告:

我认为这是一个需要周期的问题。因此,就像文件A需要文件B中的某个内容->文件B需要文件C中的某个内容->文件C需要文件A中的某个内容一样。在我的
loginActions.js
文件中创建了一个圆圈,它导致未初始化的值,但如果是这种情况,我不确定如何解决它

按下登录按钮后,我在安卓系统的
android
端也出现了同样的错误:


安卓更清楚的是,这个动作创建者确实没有定义。

这是react redux是吗

您是否已将登录组件包装在“连接”包装中

{connect}来自'react redux'

连接(mapStateToProps、mapDispatchToProps)(登录)

我不确定您的登录组件是否知道要使用哪一个操作,“setLoginDisabled()”,因此不会触发“SET_Login_DISABLED”还原程序。我刚刚用react-native设置了react-redux,并使用了“connect”包装器,效果很好


可能想试试,这是react redux是吗

您是否已将登录组件包装在“连接”包装中

{connect}来自'react redux'

连接(mapStateToProps、mapDispatchToProps)(登录)

我不确定您的登录组件是否知道要使用哪一个操作,“setLoginDisabled()”,因此不会触发“SET_Login_DISABLED”还原程序。我刚刚用react-native设置了react-redux,并使用了“connect”包装器,效果很好


可能想试试,

您应该将地图分派的分派传递给道具。试着这样做:

const mapDispatchToProps = dispatch => {
     return {
        setLoginDisabled: (status) => dispatch({ type: types.SET_LOGIN_DISABLED , payload: status })
     }
}
//OR
export function setLoginDisabled(dispatch, status) {
  return dispatch({
    type: types.SET_LOGIN_DISABLED,
    payload: status,
  })
}
然后,如果您创建了
mapDispatchToProps
const pass
mapDispatchToProps
到第二个参数:

export default connect(
  mapStateToProps,
  mapDispatchToProps 
)(Login);
否则:

export default connect(
     mapStateToProps,
     dispatch => {
         setLoginDisabled(dispatch, status)
     }
)(Login);

您应该将地图分派的分派传递给道具。试着这样做:

const mapDispatchToProps = dispatch => {
     return {
        setLoginDisabled: (status) => dispatch({ type: types.SET_LOGIN_DISABLED , payload: status })
     }
}
//OR
export function setLoginDisabled(dispatch, status) {
  return dispatch({
    type: types.SET_LOGIN_DISABLED,
    payload: status,
  })
}
然后,如果您创建了
mapDispatchToProps
const pass
mapDispatchToProps
到第二个参数:

export default connect(
  mapStateToProps,
  mapDispatchToProps 
)(Login);
否则:

export default connect(
     mapStateToProps,
     dispatch => {
         setLoginDisabled(dispatch, status)
     }
)(Login);

您似乎没有将
setLoginDisabled
传递到connect函数中

这就是为什么当您使用
console.log(setLoginDisabled)
时,
setLoginDisabled
是一个函数,但它在this.props上“不”可用(尝试
console.log(this.props.setLoginDisabled)
,它将返回未定义)

您需要像这样将
setLoginDisabled
setAuthStatus
一起传入

connect(
    mapState2Props, {
        setAuthStatus,
        "setLoginDisabled"
    }
)(Intro);
这将使
setLoginDisabled
this.props上可用


希望对您有用。

您似乎没有将
setLoginDisabled
传递到connect函数中

这就是为什么当您使用
console.log(setLoginDisabled)
时,
setLoginDisabled
是一个函数,但它在this.props上“不”可用(尝试
console.log(this.props.setLoginDisabled)
,它将返回未定义)

您需要像这样将
setLoginDisabled
setAuthStatus
一起传入

connect(
    mapState2Props, {
        setAuthStatus,
        "setLoginDisabled"
    }
)(Intro);
这将使
setLoginDisabled
this.props上可用


希望对您有用。

如果您查看
src/navigation/auth/stack.js
,很多导入语句都是不正确的,它们不应该有大括号。我对文件进行了如下重构:

import React from "react";
import { StackNavigator, NavigationActions } from "react-navigation";
import Intro from "auth/screens/Intro";
import Login from "auth/screens/Login";
import PasswordReset from "auth/screens/PasswordReset";
import RegisterNoEmail from "auth/screens/RegisterNoEmail";
import AskForMembership from "auth/screens/AskForMembership";
import CompleteAccount from "auth/screens/CompleteAccount";
import ConfirmMemberAccount from "auth/screens/ConfirmMemberAccount";
import Register from "auth/screens/Register";
import SetNewPassword from "auth/screens/SetNewPassword";
import RegisterEmailPassword from "auth/screens/RegisterEmailPassword";
import ResetLinkConfirmationAlert from "auth/screens/ResetLinkConfirmationAlert";
import DetailsConfirmation from "auth/screens/DetailsConfirmation";
import AccountCreated from "auth/screens/AccountCreated";

import BackButton from "navigation-components/BackButton";
import CustomHeader from "navigation-components/CustomHeader";
import HeaderTitle from "navigation-components/HeaderTitle";
import { v2Colors } from "theme";
import { defaultStackConfig, defaultHeaderStyles } from "../config";

const leftRegiterNavOptions = {
  title: "Register",
  headerStyle: defaultStackConfig.authHeaderStyle
};
当我更正此错误时,错误变回:

上述错误的问题是由于
react导航
无法识别从
react redux
version 7返回的对象,如我在另一篇文章中所述:


如果您查看
src/navigation/auth/stack.js
,很多导入语句都是不正确的,它们不应该有大括号。我对文件进行了如下重构:

import React from "react";
import { StackNavigator, NavigationActions } from "react-navigation";
import Intro from "auth/screens/Intro";
import Login from "auth/screens/Login";
import PasswordReset from "auth/screens/PasswordReset";
import RegisterNoEmail from "auth/screens/RegisterNoEmail";
import AskForMembership from "auth/screens/AskForMembership";
import CompleteAccount from "auth/screens/CompleteAccount";
import ConfirmMemberAccount from "auth/screens/ConfirmMemberAccount";
import Register from "auth/screens/Register";
import SetNewPassword from "auth/screens/SetNewPassword";
import RegisterEmailPassword from "auth/screens/RegisterEmailPassword";
import ResetLinkConfirmationAlert from "auth/screens/ResetLinkConfirmationAlert";
import DetailsConfirmation from "auth/screens/DetailsConfirmation";
import AccountCreated from "auth/screens/AccountCreated";

import BackButton from "navigation-components/BackButton";
import CustomHeader from "navigation-components/CustomHeader";
import HeaderTitle from "navigation-components/HeaderTitle";
import { v2Colors } from "theme";
import { defaultStackConfig, defaultHeaderStyles } from "../config";

const leftRegiterNavOptions = {
  title: "Register",
  headerStyle: defaultStackConfig.authHeaderStyle
};
当我更正此错误时,错误变回:

上述错误的问题是由于
react导航
无法识别从
react redux
version 7返回的对象,如我在另一篇文章中所述:


您能否共享使用登录组件的代码。看起来它是由父组件传递的。也只是确认一下,这个登录类文件是完整的,我没有看到render方法,So@Garry,我共享了lo所在的代码