I am writing a React Native app and using Redux.
I have followed this tutorial.
I have faced with the following warning message:
Warning: Cannot update during an existing state transition (such as within 'render' or another component's constructor). Render methods should be a pure function of props and state; constructor side-effects are an anti-pattern, but can be moved to 'componentWillMount'
Here is what I have:
MyComponent.js
import React from 'react';
import { login } from './actions'
import { connect } from 'react-redux';
import { View, Text } from 'react-native';
import { Button } from 'native-base';
class MyComponent extends React.Component {
render() {
return(
<View>
<Button onPress={() => this.props.login("username","password")}>
<Text>
Login!
<Text>
</Button>
</View>
)
}
}
function mapStateToProps(state) {
return { state: state.login }
}
function mapDispatchToProps(dispatch) {
return {
login: (username, password) => dispatch(login(username, password))
}
}
export default connect(mapStateToProps, mapDispatchToProps)(LoginScreen);
App.js
import React, { Component } from 'react';
import MyComponent from './MyComponent';
import { Provider } from 'react-redux';
import configureStore from './configureStore';
import Route from './config/Router';
export default class App extends Component {
render() {
let store = configureStore();
return (
<Provider store={store}>
<MyComponent />
</Provider>
);
}
}
configureStore.js
import { createStore } from 'redux';
import reducers from './reducers';
import thunk from 'redux-thunk';
export default function configureStore() {
let store = createStore(reducers, applyMiddleware(thunk));
return store;
}
reducers.js
import * from './constants'
import { combineReducers } from 'redux';
const initialState = {
isLoggedIn: false,
isLoggingIn: false,
username: '',
error: false
};
function loginReducer(state = initialState, action) {
console.log('Reducer is called.');
console.log('Action is ' + JSON.stringify(action));
console.log('state is ' + JSON.stringify(state));
switch (action.type) {
case LOGGING_IN:
return {
...state,
isLoggedIn: false,
isLoggingIn: true,
username: '',
error: false
}
case LOG_IN_SUCCESS:
return {
...state,
isLoggedIn: true,
isLoggingIn: false,
username: action.data.username,
error: false
}
case LOG_IN_FAILURE:
return {
...state,
isLoggedIn: false,
isLoggingIn: false,
username: '',
error: true
}
}
}
export default rootReducer = combineReducers({
loginReducer,
});
actions.js
import * './constants'
import { Actions } from 'react-native-router-flux';
export function login(username, password) {
return (dispatch) => {
dispatch(loggingIn())
//here will be some API ASYNC CALLS!
//depending on the result we will dispatch again!
myService.login(username,password).done((result) => {
if(result !== null) {
dispatch(loginSuccess(result))
} else {
dispatch(loginFailure())
}
})
}
}
function loggingIn() {
return {
type: LOGGING_IN
}
}
function loginSuccess(data) {
return {
type: LOG_IN_SUCCESS,
data: data
}
}
function loginFailure() {
return {
type: LOG_IN_FAILURE
}
}
I have debugged the code. I have seen that the warning comes right after first dispatch call! ( dispatch(loggingIn()) )
So, I don't know what the problem is.
I also wonder if this is the true use of redux and async api calls. Can you help me? Thanks a lot.