привет!
Делаю страницу авторизации. При нажатии на кнопку submit появляется эта ошибка Error: Actions must be plain objects. Use custom middleware for async actions. Использую thunk он есть в коде store.js, но почему эта ошибка возникает??помогите,пожалуйста!!
вот мой action и reducer login
import Promise from 'es6-promise';
// actions
const LOGIN_PENDING = 'LOGIN_PENDING';
const LOGIN_SUCCESS='LOGIN_SUCCESS';
const LOGIN_ERROR='LOGIN_ERROR';
export const loginPending = isLoginPending =>({
type: LOGIN_PENDING,
isLoginPending
});
export const loginSuccess = isLoginSuccess =>({
type: LOGIN_SUCCESS,
isLoginSuccess
});
export const loginError = isLoginError =>({
type: LOGIN_ERROR,
isLoginError
});
//actions which send login request and dispatch actions
export function login (username,password){
return dispatch => {
dispatch(loginPending(true));
dispatch(loginSuccess(false));
dispatch(loginError(null));
sendRequestLogin(username, password)
.then(success =>{
dispatch(loginPending(false));
dispatch(loginSuccess(true));
})
.catch(err=>{
dispatch(loginPending(false));
dispatch(loginError(err));
});
}
}
//simulate login request : username,password is admin
function sendRequestLogin (username,password) {
return new Promise ((resolve, reject)=>{
if (username === "admin" && password === "admin") {
return resolve(true)
} else {
return reject(new Error('Invalid username or password '))
}
});
}
// reducer which change data in reducer store
const loginReducer =(state = {
isLoginPending: false,
isLoginSuccess: false,
isLoginError: null
}, action) =>{
switch (action.type){
case LOGIN_PENDING:
return {
...state,
isLoginPending: action.isLoginPending
};
case LOGIN_SUCCESS:
return{
...state,
isLoginSuccess: action.isLoginSuccess
};
case LOGIN_ERROR:
return {
...state,
isLoginError: action.isLoginError
};
default:
return state;
}
};
export default loginReducer;
вот мой store
import { createStore, applyMiddleware, compose } from 'redux'
import { routerMiddleware } from 'react-router-redux'
import thunk from 'redux-thunk'
import createHistory from 'history/createBrowserHistory'
import rootReducer from './reducers/rootReducer'
export const history = createHistory()
const initialState = {} // or persisted state.
const enhancers = []
const middleware = [
thunk,
routerMiddleware(history)
]
if (process.env.NODE_ENV === 'development') {
const devToolsExtension = window.devToolsExtension
if (typeof devToolsExtension === 'function') {
enhancers.push(devToolsExtension())
}
}
const composedEnhancers = compose(
applyMiddleware(...middleware),
...enhancers
)
export default createStore(
rootReducer,
initialState,
composedEnhancers
)
вот index.js
import React from 'react';
import ReactDOM from 'react-dom';
import MuiThemeProvider from 'material-ui/styles/MuiThemeProvider';
import { createStore, applyMiddleware, combineReducers } from 'redux'
import { Provider } from 'react-redux'
import { createLogger } from 'redux-logger'
import thunk from 'redux-thunk'
import './index.css';
import App from './containers/App';
import registerServiceWorker from './registerServiceWorker';
import { loadState, saveState } from './modules/localStorage'
import { initialize, addTranslation, localeReducer, setActiveLanguage } from 'react-localize-redux';
import { Router, Route, IndexRoute, browserHistory } from 'react-router'
import rootReducer from './reducers/rootReducer'
const translations = require('./global.locale.json');
const languages = ['en', 'fi'];
// ACTION
const RANDOMIZE = 'RANDOMIZE';
const actionRandomize = {
type: RANDOMIZE,
text: 'dddd'
};
const маке10 = {
type: 'МАКЕ10'
};
const actionADDSOMETHING = {
type: 'ADD_SOMETHING',
value: {}
};
const addSomething = (thing) => {
return {
type: 'ADD_SOMETHING',
thing
}
};
// end ACTION
// STATE
const initialState = loadState();
onsole.log(store.getState())
let store = createStore(combineReducers(
{potato: rootReducer,
locale: localeReducer}),
window.STATE_FROM_SERVER)
store.subscribe(() => {
saveState(store.getState())
})
// Log the initial state
console.log(store.getState())
store.dispatch(actionRandomize);
console.log(store.getState())
store.dispatch(маке10);
console.log(store.getState())
store.dispatch(actionADDSOMETHING);
console.log(store.getState())
store.dispatch(addSomething({"ggg":"00"}));
// const defaultLanguage = storage.getItem('language') || languages[0];
const defaultLanguage = languages[0];
store.dispatch(initialize(languages, { defaultLanguage }));
store.dispatch(addTranslation(translations));
// store.dispatch(setActiveLanguage('en'));
ReactDOM.render(
<Provider store={store}>
<MuiThemeProvider>
<App />
</MuiThemeProvider>
</Provider>, document.getElementById('root'));
registerServiceWorker();
вот форма Login.js
//todo translate???
import React, { Component } from 'react';
import ReactDOM from 'react-dom';
import { Link } from 'react-router';
import TextField from 'material-ui/TextField';
import RaisedButton from 'material-ui/RaisedButton';
import { getTranslate, getActiveLanguage } from 'react-localize-redux'
import { connect } from 'react-redux';
import {Redirect} from 'react-router-dom';
import { login } from '../reducers/login-reducer';
class Login extends Component {
constructor(props) {
super(props);
this.state = {
username:'',
password:''
};
this.onSubmit = this.onSubmit.bind(this);
};
render() {
let { username, password } = this.state,
{ isLoginPending, isLoginSuccess, isLoginError } = this.props;
return (
<div className="form-login" onSubmit={this.onSubmit}>
<h1><b>Sisäänkirjautuminen</b></h1>
<h3>Kirjaudu sisään antamalla käyttäjätunnus ja salasana.</h3>
<form name ="loginForm">
<TextField
type="text"
floatingLabelText="Username"
onChange={(e) =>this.setState({username: e.target.value})}
value={username}
fullWidth={true}
/>
<TextField
type="password"
floatingLabelText="Password"
onChange={(e) =>this.setState({password: e.target.value})}
value={password}
fullWidth={true}
/>
<br/>
<RaisedButton label="Login" type="submit"/>
<div className="message">
{ isLoginPending && <div>Please wait...</div> }
{ isLoginSuccess && <div>Success</div>}
{ isLoginError && <div>{ isLoginError.message }</div> }
</div>
</form>
</div>
)}
onSubmit =(e)=> {
e.preventDefault();
let { username, password }=this.state;
this.props.login(username,password);
this.setState({
username: '',
password: ''
});
console.log('click')
}
}
const mapStateToProps = (state)=>{
return {
isLoginPending: state.isLoginPending,
isLoginSuccess: state.isLoginSuccess,
isLoginError: state.isLoginError
};
};
const mapDispatchToProps = (dispatch) => {
return {
login: (username, password) => dispatch(login(username,password))
}
};
export default connect(mapStateToProps, mapDispatchToProps)(Login);