反应 - 按下按钮时的本机' Redux Uncaught Error: Actions must be plain objects. Use custom middleware for async



所以我是React Native和Redux的新手。我正在将Redux集成到React Native中,除了调度操作外,一切都很好。每次我试图调度操作时,我都会收到错误"Redux Uncaught error":操作必须是普通对象。为异步操作使用自定义中间件。我甚至试着整合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; 
}

尝试按照约定{ type: SET_IS_LOGGED_IN, payload: value }构建操作。我认为{value}试图破坏value,而不是在你的动作对象中设置一个新的道具value: true。如果有效,请告诉我。

对于异步操作,您不应该执行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 dosnt返回一个操作对象(带有操作键的对象(,setIsRecordedIn dosn返回一个动作对象,而不是返回一个thunk,一个函数;。

相关内容

最新更新