永久违反:无效的Hooks呼叫。挂钩调用只能在功能组件内部进行

时间:2019-05-09 18:04:15

标签: react-native redux

您好,在LoginScreen.js的Connect()函数中收到此错误。在评论它的工作正常。我猜我的商店设置不正确,或者我无法将LoginScreen组件连接到Redux商店。

  

LoginScreen.js

import React, { Component } from "react";
import PhoneInput from "react-native-phone-input";
import { connect } from "react-redux";
import { View, StatusBar } from "react-native";
import { Container, Item, Input, Button, Text } from "native-base";
import {
  phoneChanged,
  codeChanged,
  onCodeDispatched,
  onPhoneLogin,
  clearAuth,
  onSignOut
} from "../Actions/AuthActions";
//import firebase from "react-native-firebase";
import { auth } from "../Config/firebase";

export class LoginScreen extends Component {
}

export default connect(
  null, // passing null just for testing
  null
)(LoginScreen);
  

Store.js

import ReduxThunk from "redux-thunk";
import { createStore, applyMiddleware, compose } from "redux";
import reducer from "../Reducers/index";

let composeEnhancers = compose;
/*  eslint no-undef: 0    */
if (__DEV__) {
  /*  eslint no-underscore-dangle: 0    */
  composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose;
}

const store = createStore(
  reducer,
  {},
  composeEnhancers(applyMiddleware(ReduxThunk))
);

export { store };
  

AuthReducer.js

import {
  LOGIN_FAIL,
  LOGIN_SUCCESS,
  LOGIN_USER,
  PHONE_CHANGED,
  CODE_SENT_ERROR,
  CODE_CHANGED,
  CODE_DISPATCHED,
  LOGIN_USER_PHONE,
  CODE_SENT,
  CODE_NOT_CONFIRMED,
  LOGOUT,
  SET_USER_OBJECT,
  CLEAR_AUTH
} from "../Actions/ActionTypes";

const INITIAL_STATE = {
  phone: "+30",
  user: null,
  message: "",
  loading: false,
  codeInput: "",
  confirmResult: null
};

const AuthReducer = (state = INITIAL_STATE, action) => {
  console.log(action);

  switch (action.type) {
    case PHONE_CHANGED:
      return {
        ...state,
        phone: action.payload
      };
    case CODE_CHANGED:
      return {
        ...state,
        codeInput: action.payload
      };
    case LOGIN_USER:
      return {
        ...state,
        loading: true,
        message: ""
      };
    case LOGIN_USER_PHONE:
      return {
        ...state,
        loading: true,
        message: "Sending code...",
        phone: action.payload
      };
    case CODE_DISPATCHED:
      return {
        ...state,
        loading: true,
        message: ""
      };
    case CODE_SENT:
      return {
        ...state,
        loading: true,
        message: "Code has been sent!",
        confirmResult: action.payload
      };
    case CODE_SENT_ERROR:
      return {
        ...state,
        loading: false,
        message: `Sign in with Phone number error: ${action.payload}`,
        confirmResult: null
      };
    case SET_USER_OBJECT:
      return {
        ...state,
        user: action.payload
      };
    case CODE_NOT_CONFIRMED:
      return {
        ...state,
        message: `Code confirmation error: ${action.payload}`
      };
    case LOGIN_SUCCESS:
      return {
        ...INITIAL_STATE,
        user: action.payload,
        message: "login Success"
      };
    case LOGIN_FAIL:
      return {
        ...state,
        message: "Authentication Failed.",
        loading: false,
        password: "",
        phone: "+91"
      };
    case LOGOUT:
      return {
        ...state,
        message: "",
        user: null
      };
    case CLEAR_AUTH:
      return {
        ...state,
        ...INITIAL_STATE
      };
    default:
      return state;
  }
};

export default AuthReducer;
  

Root.js

import React from "react";
import { Provider } from "react-redux";
import { Navigator } from "./Navigation/Index";
import { store } from "./Store/Index";

export default class Root extends React.Component {
  render() {
    return (
      <Provider store={store}>
        <Navigator />
      </Provider>
    );
  }
}
  

AuthActions.js

//import { firebase } from "react-native-firebase";
import * as actionTypes from "./ActionTypes";
import { auth } from "../Config/firebase";

const phoneChanged = text => {
  return {
    type: actionTypes.PHONE_CHANGED,
    payload: text
  };
};

const onLoginSuccess = (dispatch, user) => {
  dispatch({
    type: actionTypes.LOGIN_SUCCESS,
    payload: user
  });
};

const signOut = dispatch => {
  dispatch({
    type: actionTypes.LOGOUT
  });
};

const onPhoneLogin = phone => {
  return dispatch => {
    dispatch({
      type: actionTypes.LOGIN_USER_PHONE
    });
    auth
      .signInWithPhoneNumber(phone)
      //  sign in success
      .then(confirmResult => {
        onCodeSent(dispatch, confirmResult);
      })
      //  sign in error
      .catch(error => onCodeSentError(dispatch, error));
  };
};

const codeChanged = text => {
  return {
    type: actionTypes.CODE_CHANGED,
    payload: text
  };
};

const onCodeSent = (dispatch, confirmResult) => {
  dispatch({
    type: actionTypes.CODE_SENT,
    payload: confirmResult
  });
};

const onCodeConfirmError = (dispatch, error) => {
  dispatch({
    type: actionTypes.CODE_NOT_CONFIRMED,
    payload: error
  });
};

const onCodeDispatched = code => {
  return (dispatch, getState) => {
    getState()
      .auth.confirmResult.confirm(code)
      .then(user => onLoginSuccess(dispatch, user))
      .catch(error => onCodeConfirmError(dispatch, error));
  };
};

const onCodeSentError = (dispatch, error) => {
  dispatch({
    type: actionTypes.CODE_SENT_ERROR,
    payload: error
  });
};

const onSignOut = () => {
  return dispatch => {
    auth
      .signOut()
      .then(() => signOut(dispatch))
      .catch(error => console.log(error));
  };
};

const clearAuth = () => {
  return dispatch => {
    dispatch({
      type: actionTypes.CLEAR_AUTH
    });
  };
};

export {
  onSignOut,
  clearAuth,
  codeChanged,
  onPhoneLogin,
  phoneChanged,
  onCodeDispatched
};

这个想法基本上是要调用LoginScreen,它是“ Auth” StackNavigator的一部分,并呈现PhoneNumberInput和OTP。

1 个答案:

答案 0 :(得分:0)

React-redux(> 7.0.1)使用钩子,而React-native(<0.59)还不支持Hooks。

您可以在应用程序文件夹中运行npm ls react-native来检查使用的版本。

如果您发现其中一个以上,则可能还会造成问题。 more on it

有两种解决方法

将react本机版本升级到0.59.0

OR

将React Redux版本降级到6.0.1

希望对您有帮助。