react-native - 不变违规:无效的 Hooks 调用。Hooks 调用只能在函数组件内部进行
问题描述
您好,在 LoginScreen.js 的 Connect() 函数中出现此错误。在评论它工作正常。我猜我的商店没有正确设置,或者我无法将 LoginScreen 组件连接到 Redux 商店。
登录屏幕.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;
根.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。
解决方案
React-redux (> 7.0.1) 使用 hook & React-native (< 0.59) 还不支持 Hooks。
您可以npm ls react-native
在应用程序文件夹中运行以检查您使用的版本。
如果您发现其中不止一个,这也可能会产生问题。更多关于它
有两种解决方案
将 react 原生版本升级到 0.59.0
或者
将 react redux 版本降级到 6.0.1
我希望它对你有帮助。
推荐阅读
- javascript - 一个提交按钮 - 两个半径形式。如何在烧瓶中收集提交的值
- javascript - 在vue js中将输入文本添加到复选框的值
- gdb - GDB错误gdb:加载共享库时出错:libffi.so.7:无法打开共享对象文件:没有这样的文件或目录
- python - Python:将类中的字典(以类方法作为值)移动到另一个文件
- c++ - 是否可以在 C++ 中的单个操作中同时获得除法的模数和商?
- reactjs - 输入更改时更改映射列表
- c++ - m_hAccel = ::LoadAccelerators(AfxGetInstanceHandle(), MAKEINTRESOURCE (IDR_ACCELTEST)) 中的 :: 是什么意思;
- typescript - 如何使用 fastify 为不同的参数创建一个具有多个模式的路由?
- ibm-watson - 为什么我看到“创建服务经销商渠道 2c95500b-ea86-4b13-8bb5-b2f0c2fa8200 无效”。每当我尝试打开云 obj 存储时?
- java - Android Studio:无法初始化编辑器