React - Native ' Redux 未捕获错误:操作必须是普通对象。按下按钮时使用自定义中间件进行异步操作
Posted
技术标签:
【中文标题】React - Native \' Redux 未捕获错误:操作必须是普通对象。按下按钮时使用自定义中间件进行异步操作【英文标题】:React - Native ' Redux Uncaught Error: Actions must be plain objects. Use custom middleware for async actions' on button pressReact - Native ' Redux 未捕获错误:操作必须是普通对象。按下按钮时使用自定义中间件进行异步操作 【发布时间】:2020-06-18 15:16:03 【问题描述】:所以我是 React-Native 和 Redux 的新手。我正在将 Redux 集成到 React-Native 中,一切都运行良好,除了调度操作。每次我尝试调度操作时,我都会收到错误“Redux Uncaught Error: Actions must be plain objects”。使用自定义中间件进行异步操作'。我什至尝试集成 react-thunk,但没有成功。我什至尝试使用store.dispatch(setIsLoggedIn(true))
直接在商店发货。我的应用程序应该支持登录功能,我想设置状态,以便我知道我的用户是否已登录。
我的商店是这样初始化的:
import createStore, compose, applyMiddleware from 'redux';
import rootReducer from '../reducers/index';
import thunk from 'redux-thunk';
const storeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose;
const store = createStore(rootReducer, storeEnhancers(applyMiddleware(thunk)));
export default store;
我的减速器是这样的:
import SET_IS_LOGGED_IN, SET_USER, SET_TOKEN from '../actions/index'
const initialState =
loggedIn: false,
user: null,
token: "",
//slice zum removen
function rootReducer(state=initialState, action)
switch (action.type)
case SET_IS_LOGGED_IN:
return Object.assign(, state,
loggedIn: true
)
break;
case SET_USER:
return Object.assign(, state,
user: action.user
)
break;
case SET_TOKEN:
return Object.assign(, state,
token: action.token
)
break;
default:
// Anweisungen werden ausgeführt,
// falls keine der case-Klauseln mit expression übereinstimmt
break;
return state;
export default rootReducer;
我的动作是这样定义的:
export const SET_IS_LOGGED_IN='SET_IS_LOGGED_IN'
export function setIsLoggedIn(value)
return
type: SET_IS_LOGGED_IN,
value
;
export function setIsLoggedInAsync(value)
return dispatch =>
setTimeout(() =>
dispatch(setIsLoggedIn(value))
,1000);
;
export const SET_USER='SET_USER'
export function setUser(user)
return
type: SET_USER,
user
;
export const SET_TOKEN='SET_TOKEN'
export function setToken(token)
return
type: SET_TOKEN,
token
;
我的主要组件是这样的:
import React, Component from 'react';
import ScrollView, Text, TextInput, View, Button, StyleSheet, Image, TouchableOpacity, Linking from 'react-native';
import UserLogin from '../model/UserLogin';
import loginCall from '../api/User-Api';
import Logo from '../../assets/logo.png';
import connect from 'react-redux';
import setIsLoggedIn, setUser, setToken from '../redux/actions/index'
import store from '../redux/store/index'
const mapStateToProps=(state)=> (
test: state.test
)
const mapDispatchToProps = (dispatch) => (
setIsLoggedIn: value => dispatch(setIsLoggedIn(true)),
setUser: user => dispatch(setUser(user)),
setToken: token => dispatch(setToken(token)),
)
class Login extends Component
constructor(props)
super(props);
this.state =
email: "null",
password:"null",
wrongPw : false,
title: "bla"
this._onPressButton = this._onPressButton.bind(this);
this._onRegisterButton = this._onRegisterButton.bind(this);
componentDidMount()
console.log(store.getState());
componentWillUnmount()
console.log(store.getState());
_onRegisterButton()
var link = "";
Linking.canOpenURL(link).then(supported =>
if (supported)
Linking.openURL(link);
else
console.log("Don't know how to open URI: " + this.props.url);
);
_onPressButtonTest()
store.dispatch(setIsLoggedIn(true))
_onPressButton()
//let username = this.state.email;
this.setState(wrongPw: false);
var user = new UserLogin();
user.email = this.state.email;
user.password = this.state.password;
loginCall(user).then((response) =>
console.log(response);
// Set token for api calls const token = response.data;
if(response.status == 200)
console.log(response.data)
this.props.navigation.navigate('MainPage')
this.props.setIsLoggedInProp(true);
//this.props.setIsLoggedIn(true);
//this.props.setUser(user);
//this.props.setToken(response.data);
// <Text style=styles.forgot>this.props.test</Text>
)
.catch((error) =>
this.setState(wrongPw: true);
console.log(error);
);
render()
return (
<View style=styles.container>
<TouchableOpacity onPress=this._onPressButtonTest.bind(this) style=styles.loginBtn>
<Text style=styles.loginText>TESTING</Text>
</TouchableOpacity>
<Image source=Logo style=styles.logo/>
<TextInput style=styles.inputView placeholder='Email' placeholderTextColor="#1F676B" onChangeText=(value) => this.setState(email: value) />
<TextInput style=styles.inputView secureTextEntry=true placeholder='Password' placeholderTextColor="#1F676B" onChangeText=(value) => this.setState(password: value) />
this.state.wrongPw && <Text style=styles.error>Email oder Passwort ist ungültig.</Text>
<TouchableOpacity onPress=() => this.props.navigation.navigate('PasswortVergessen')>
<Text style=styles.forgot>Passwort vergessen?</Text>
</TouchableOpacity>
<TouchableOpacity onPress=this._onPressButton.bind(this) style=styles.loginBtn>
<Text style=styles.loginText>LOGIN</Text>
</TouchableOpacity>
<TouchableOpacity onPress=this._onRegisterButton.bind(this)>
<Text style=styles.register>Registrieren</Text>
</TouchableOpacity>
</View>
)
//null wenn ich nichts will von states
export default connect(mapStateToProps, mapDispatchToProps)(Login);
const styles = StyleSheet.create(
container:
flex: 1,
backgroundColor: '#1F676B',
alignItems: 'center',
justifyContent: 'center',
,
logo:
width: 280,
height: 140,
marginBottom:30,
,
inputView:
width:275,
backgroundColor:"#a5c2c3",
borderRadius:25,
height:50,
marginBottom:20,
justifyContent:"center",
padding:10,
color:"#1F676B",
fontSize:15,
fontWeight: "bold"
,
inputText:
height:50,
color:"#1F676B"
,
forgot:
color:"white",
fontSize:12,
marginBottom:10,
,
register:
color:"white",
fontSize:16,
,
loginText:
color:"#1F676B",
fontSize:19,
fontWeight: "bold"
,
loginBtn:
width:275,
backgroundColor:"#ffffff",
borderRadius:25,
height:50,
alignItems:"center",
justifyContent:"center",
marginTop:40,
marginBottom:10
,
error:
color:"#fff",
fontSize:19,
marginBottom:20
,
)
我正在寻找过去几个小时的错误,但似乎无法取得进展。任何提示都表示赞赏。
编辑:所以错误出现在操作中。我的行为定义错误。 这对我来说是这样的:
export function setIsLoggedIn(value)
const action =
type: SET_IS_LOGGED_IN,
value
;
return action;
【问题讨论】:
【参考方案1】:尝试按照约定 type: SET_IS_LOGGED_IN, payload: value
构建操作。我认为value
试图解构value
,而不是在你的动作对象中设置一个新的道具value: true
。让我知道它是否有效。
【讨论】:
【参考方案2】:对于异步操作,您不应执行 dispath 并调度操作,而是将其作为第二个参数传递给 setIsLogedIn 函数
export function setIsLoggedInAsync(value)
return dispatch =>
setTimeout(() =>
dispatch(setIsLoggedIn(value))
,1000);
;
你需要在mapDispatchToProps函数中提供这种方式,
setIsLoggedIn: value => setIsLoggedIn(true)(dispatch), // do this
// setIsLoggedIn: value => dispatch(setIsLoggedIn(true)) dont
在您的方法中,您正在执行调度,并且 setIsLoggedIn 会返回一个动作对象(带有动作键的对象),而 setIsLoggedIn 不会返回一个动作对象,而是返回一个 thunk,一个函数;。
【讨论】:
以上是关于React - Native ' Redux 未捕获错误:操作必须是普通对象。按下按钮时使用自定义中间件进行异步操作的主要内容,如果未能解决你的问题,请参考以下文章
React Native 已经有了异步存储。为啥我应该在我的 react native 应用中使用 Redux 和 Redux Thunk?