Action calling recursively in my middleware when data fetch - javascript

I have component App which render its children and Header component. I use Preloader from react-loader repo which takes bool loaded and render preloader or page in depended from bool. When App componentWillMount, data fetch via actionCreators, action use redux-api-middleware, then when execute render in App, Header fetch data via actionCreator boundGetPhotos which execute recursively look PHOTOS_GET_SUCCESS in console screenshot here i log action.type in my fetchingMiddleware . All actions pass from my middleware fetchingMiddleware look belowe. Which can be reasons of recursive behavior why it execute again and again and how i can solve it
App
import React, { Component, PropTypes } from 'react';
import Counterpart from 'counterpart';
import { connect } from 'react-redux';
import Loader from 'react-loader';
import { bindActionCreators } from 'redux';
import { getFriends, getMessages } from '../data/Data.Actions';
import { getUsers } from '../users/Users.Actions';
import Header from './Header';
class App extends Component {
componentWillMount() {
const { boundGetFriends, boundGetMessages, boundGetUsers } = this.props;
boundGetFriends();
boundGetMessages();
boundGetUsers();
}
render() {
const { children, fetching } = this.props;
return (
<Loader loaded={!fetching.size}>
<div>
<Header/>
{children}
</div>
</Loader>
);
}
}
App.propTypes = {
boundGetUsers: PropTypes.func,
boundGetMessages: PropTypes.func,
boundGetFriends: PropTypes.func,
fetching: PropTypes.array
};
export default connect((store) => {
return {
fetching: store.fetching
};
}, (dispatch) => {
return {
boundGetUsers: bindActionCreators(getUsers, dispatch),
boundGetFriends: bindActionCreators(getMessages, dispatch),
boundGetMessages: bindActionCreators(getFriends, dispatch)
};
})(App);
Header
import React, { Component, PropTypes } from 'react';
import React, { Component, PropTypes } from 'react';
import { Navbar, Nav, NavItem, NavDropdown, MenuItem } from 'react-bootstrap';
import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';
import ImmutablePropTypes from 'react-immutable-proptypes';
import { getPhotos } from '../user/User.Actions';
class Header extends Component {
componentWillMount() {
const { boundGetPhotos } = this.props;
boundGetPhotos();
}
render() {
return (
<Navbar fluid collapseOnSelect>
<Navbar.Brand>
MyProject
</Navbar.Brand>
</Navbar>
);
}
}
Header.propTypes = {
boundGetPhotos: PropTypes.func.isRequired
};
export default connect((store) => null, (dispatch) => {
return {
boundGetPhotos: bindActionCreators(getPhotos, dispatch)
};
})(Header);
FetchingMiddleware
import { startFetching, endFetching } from './FetchingMiddleware.Actions';
export default store => next => action => {
console.log(action.type);
if (typeof action !== 'function' && action.type.search(/REQUEST/) !== -1) {
store.dispatch(startFetching());
}
if (typeof action !== 'function' && action.type.search(/SUCCESS|FAILURE/) !== -1) {
store.dispatch(endFetching());
}
next(action);
};
FetchingMiddlewareReducers
import Immutable from 'immutable';
import { END_FETCHING, START_FETCHING, RESET_FETCHING } from './FetchingMiddleware.Actions';
import createReducer from '../utils/utils';
function addFetching(state, action) {
return state.push(true);
}
function removeFetching(state, action) {
return state.pop();
}
function resetFetching(state, action) {
return Immutable.List();
}
export default createReducer({
[END_FETCHING]: removeFetching,
[START_FETCHING]: addFetching,
[RESET_FETCHING]: resetFetching
}, Immutable.List());
FetchingMiddlewareActions
export const END_FETCHING = 'END_FETCHING';
export const START_FETCHING = 'START_FETCHING';
export const RESET_FETCHING = 'RESET_FETCHING';
export function endFetching() {
return {
type: END_FETCHING
};
}
export function startFetching() {
return {
type: START_FETCHING
};
}
export function resetFetching() {
return {
type: RESET_FETCHING
};
}
getPhotos
import { CALL_API } from 'redux-api-middleware';
export const PHOTOS_GET_SUCCESS = 'PHOTOS_GET_SUCCESS';
export function getPhotos() {
return {
[CALL_API]: {
endpoint: '/photos',
method: 'GET',
headers: {
'Content-Type': 'application/json'
},
credentials: 'include',
types: ['REQUESTPHOTOS', PHOTOS_GET_SUCCESS, 'FAILURE']
}
};
}

Your <Header /> component should be a pure component that knows nothing about your state container (Redux) or dispatch.
Using the approach you have here would litter your component tree with 'connect' and add awareness of Redux to all of your components. This is bad practice in terms of scalability - what if you wanted to replace Redux with another state container?.
I would recommend that all state and actions should be bound to props and passed down the tree into your components such as the <Header /> component.
This should also resolve the issues you are having.
App
import React, { Component, PropTypes } from 'react';
import Counterpart from 'counterpart';
import { connect } from 'react-redux';
import Loader from 'react-loader';
import { getMasterDataSchema, getMasterDataData } from '../masterdata/MasterData.Actions';
import { getQuestionnaireSchema } from '../questionnaireschema/QuestionnaireSchema.Actions';
import Header from './Header';
class App extends Component {
componentWillMount() {
const {
GetMasterDataData,
GetMasterDataSchema,
GetQuestionnaireSchema
} = this.props;
GetMasterDataData();
GetMasterDataSchema();
GetQuestionnaireSchema();
}
render() {
const { children, fetching, GetPrincipal } = this.props;
return (
<Loader loaded={!fetching.size}>
<div>
<Header GetPrincipal={GetPrincipal} />
{children}
</div>
</Loader>
);
}
}
App.propTypes = {
GetPrincipal: PropTypes.func,
GetQuestionnaireSchema: PropTypes.func,
GetMasterDataSchema: PropTypes.func,
GetMasterDataData: PropTypes.func,
fetching: PropTypes.array
};
export default connect(({ fetching }) => ({
fetching
}), {
GetPrincipal,
GetQuestionnaireSchema,
GetMasterDataData,
GetMasterDataSchema,
})(App);
Header
import React, { Component, PropTypes } from 'react';
import { Navbar, Nav, NavItem, NavDropdown, MenuItem } from 'react-bootstrap';
export default class Header extends Component {
componentWillMount() {
const { GetPrincipal } = this.props;
GetPrincipal();
}
render() {
return (
<Navbar fluid collapseOnSelect>
<Navbar.Brand>
EMS
</Navbar.Brand>
</Navbar>
);
}
}
Header.propTypes = {
GetPrincipal: PropTypes.func.isRequired
};

Related

Dispatched data in useContext isnt updadet in all of my Components

I have the following problem. I try to get set State in one Component with useReducer.
That is my Component where I use the dispatch function:
import { useContext } from "react";
import { useEffect } from "react";
import { Context } from "../state/context";
import { setTeams } from "../state/reducer";
import { RenderNavBar } from "./RenderNavBar";
export const GetTeamsByFiles = () => {
const {state,dispatch}=useContext(Context);
useEffect(() => {
dispatch(setTeams([
{ name: "FKP1-Komplett", members: ["Lars", "Tobias", "Falko", "Sami"] },
{ name: "FKP1-Entwickler", members: ["Lars", "Tobias"] },
{
name: "FKP2-Komplett",
members: ["Tessa", "Volker", "Robert", "Viktor", "Ahmed", "Patrick"],
},
{
name: "FKP2-Entwickler",
members: ["Tessa", "Volker", "Robert", "Viktor"],
},
])
)
}, []);
return (
<>
<RenderNavBar teams={state.teams}/>
</>
);
};
and I want to get access to the updated state in another Component with useContext
here you can see the component where I want to have my updated data
import { useEffect } from "react";
import { useReducer ,useContext} from "react";
import { Form } from "react-bootstrap";
import { useParams } from "react-router-dom";
import { Context } from "../state/context";
export interface IProps {
}
export const RenderCheckbox = () => {
const {state}=useContext(Context);
let { teamName }:any = useParams();
useEffect(()=>{
console.log(state)
},[state])
return (
<>
{teamName}
<Form.Check
type={"checkbox"}
id={`default-checkbox`}
label={`default checkbox`}
/>
</>
);
};
That is my App Component.
import "bootstrap/dist/css/bootstrap.min.css";
import "./App.css";
import { GetTeamsByFiles } from "./components/GetTeamsByFiles";
import { RenderCheckbox } from "./components/RenderCheckbox";
import { BrowserRouter, BrowserRouter as Router, Route, Switch } from "react-router-dom";
import { useContext, useMemo, useReducer } from "react";
import { reducer } from "./state/reducer";
import { initialState } from "./state/state";
import { Context } from "./state/context";
function App() {
const [state, dispatch] = useReducer(reducer, initialState);
return (
<div className="App">
<Context.Provider value={{state,dispatch}}>
<BrowserRouter>
<Switch>
<Route exact path="/" component={GetTeamsByFiles}></Route>
<Route path="/:teamName" component={RenderCheckbox}></Route>
</Switch>
</BrowserRouter>
</Context.Provider>
</div>
);
}
export default App;
And here is my created Context
import React from "react";
import { Actions } from "./actions";
import { initialState, State } from "./state";
export const Context = React.createContext<{
state: State;
dispatch: React.Dispatch<Actions>;
}>({
state: initialState,
dispatch: () => undefined,
});
Last but nor least my reducer
import { ITeam } from "../interfaces/ITeam";
import { Actions, ActionType, SetTeams } from "./actions";
import { State } from "./state";
export const reducer=(state: State, action: Actions): State=> {
switch (action.type) {
case ActionType.SetTeams:
return { ...state, teams: action.payload };
default:
return state;
}
}
export const setTeams = (teams: ITeam[]): SetTeams => ({
type: ActionType.SetTeams,
payload: teams,
});
It is updated in the first component but not in the second. What am I doing wrong?
Please be indulgent with me, its my first question on stack overflow :)
Which information more do you need to help me?

Cannot read property 'type' of undefined - redux

I'm trying to dispatch an action, but it returns "type" of undefined. I suspect Redux Thunk is not working properly.
Before I was dispatching the same action from the parent component and it was working.
Entry point
import React, { Component } from 'react'
import { Provider } from 'react-redux'
import configureStore from '../ConfigureStore'
import '../App.css';
import App from './theapp/theAppContainer';
const store = configureStore()
class Root extends Component {
render() {
return (
<Provider store={store}>
<App />
</Provider>
)
}
}
export default Root;
Store
import { createStore, applyMiddleware } from 'redux'
import thunkMiddleware from 'redux-thunk'
import { createLogger } from 'redux-logger'
import allReducers from './reducers/index'
const loggerMiddleware = createLogger()
export default function configureStore() {
return createStore(
allReducers,
applyMiddleware(thunkMiddleware, loggerMiddleware)
)
}
The app - routing. Before I was dispatching the action at this level and it was working.
import React, { Component } from 'react'
import Cards from '../templates/cards/CardsContainer'
import EditApp from '../pages/editApp/EditApp'
import NewApp from '../pages/NewApp'
import AppReport from '../pages/AppReport'
import { Route, Switch, HashRouter } from 'react-router-dom'
export default class TheApp extends Component {
constructor(props) {
super(props)
}
render() {
const appId = window.location.href.split('id=')[1];
return (
<HashRouter>
<Switch>
<Route exact path="/" component={Cards} />
<Route path="/app" component={EditApp} />
<Route exact path="/new" component={NewApp} />
<Route path="/report" component={AppReport} />
</Switch>
</HashRouter>
)
}
}
The container where I dispatch the action
import { connect } from 'react-redux'
import Cards from './Cards'
import {
fetchAppsData
} from '../../../actions'
function mapStateToProps(state){
return {
apps: state.apps
}
}
function matchDispatchToProps(dispatch){
return dispatch(fetchAppsData)
}
export default connect(mapStateToProps, matchDispatchToProps)(Cards)
Action
import fetch from 'cross-fetch'
import * as helpers from '../Helpers';
export const REQUEST_ITEMS = 'REQUEST_ITEMS'
export const RECEIVE_ITEMS = 'RECEIVE_ITEMS'
export function fetchAppsData() {
return (dispatch) => {
return dispatch(fetchItems())
}
}
function fetchItems() {
return dispatch => {
dispatch(requestItems())
return fetch(helpers.appData)
.then(response => response.json())
.then(json => dispatch(receiveItems(json)))
}
}
function requestItems() {
return {
type: REQUEST_ITEMS
}
}
function receiveItems(json) {
return {
type: RECEIVE_ITEMS,
items: json,
receivedAt: Date.now()
}
}
The reducer
import {
REQUEST_ITEMS,
RECEIVE_ITEMS
} from '../actions/apps-actions'
export default function apps(
state = {
isFetching: false,
items: []
},
action
) {
switch (action.type) {
case REQUEST_ITEMS:
return Object.assign({}, state, {
isFetching: true
})
case RECEIVE_ITEMS:
return Object.assign({}, state, {
isFetching: false,
items: action.items
})
default:
return state
}
}
Try changing
function matchDispatchToProps(dispatch){
return dispatch(fetchAppsData)
}
Into this:
function matchDispatchToProps(dispatch){
return {
fetchAppsData: () => dispatch(fetchAppsData())
}
}
Also the function should be called “mapDispatchToProps” but that is not important for your problem.
I believe calling
dispatch(fetchAppsData)
isn't correct, fetchAppsData is a thunk creator, not a thunk directly. Instead you would want to do
dispatch(fetchAppsData())

Reactjs recieves error even when backend is showing 200 OK

When I send a GET request from my ReactJS frontend, It recieves an error even though my django backend shows [10/Mar/2018 23:31:08] "GET /post/ HTTP/1.1" 200 930 in the terminal.
I'm using redux sagas.
src/index.js
import React from 'react';
import ReactDOM from 'react-dom';
import { Provider } from 'react-redux';
import { createStore, applyMiddleware } from 'redux';
import { BrowserRouter, Route, Switch, Redirect } from 'react-router-dom';
import createSagaMiddleware from 'redux-saga'
import rootSaga from './sagas'
import rootReducer from './reducers';
import PostsIndex from './components';
const sagaMiddleware = createSagaMiddleware();
const store = createStore(
rootReducer,
applyMiddleware(sagaMiddleware)
);
sagaMiddleware.run(rootSaga);
ReactDOM.render(
<Provider store={store}>
<BrowserRouter>
<div>
<Switch>
<Route path="/" component={PostsIndex}/>
</Switch>
</div>
</BrowserRouter>
</Provider>
, document.querySelector('.container'));
src/components/index.js
import React, { Component } from 'react';
import { fetchPosts } from '../actions';
import { connect } from 'react-redux';
import { Link } from 'react-router-dom';
import _ from 'lodash';
class PostsIndex extends Component {
componentDidMount() {
this.props.fetchPosts();
}
renderPosts() {
return _.map(this.props.posts, (post) => {
return(
<li className="list-group-item" key={post.id}>
{post.text}
</li>
)
})
}
render() {
const { posts } = this.props
if (posts.isLoading) {
return (
<div>
<h3>Loading...</h3>
</div>
)
} else if (posts.error) {
return (
<div>
<h3>Error getting posts</h3>
<h2>{JSON.stringify(posts.error)}</h2>
</div>
)
} else {
return (
<div>
<div className="text-xs-right">
<Link className="btn btn-primary" to="/posts/new">
Add a Post
</Link>
</div>
<h3>Posts</h3>
<ul className="list-group">
{this.renderPosts()}
</ul>
</div>
);
}
}
}
function mapStateToProps({ posts }){
return { posts }
}
export default connect(mapStateToProps, { fetchPosts })(PostsIndex);
src/actions/index.js
export const FETCH_POSTS = 'fetch_posts';
export function fetchPosts() {
return { type: FETCH_POSTS };
}
src/api/index.js
import axios from 'axios';
const ROOT_URL = 'http://127.0.0.1:8000';
export function fetch(endpoint) {
return axios.get(`${ROOT_URL}/${endpoint}/`)
.then(response => ({ response }))
.catch(error => ({ error }));
}
src/reducers/index.js
import { combineReducers } from 'redux';
import { POSTS_REQUESTED, POSTS_RECEIVED, POSTS_REQUEST_FAILED } from '../sagas';
import _ from 'lodash';
function postsReducer(state = {}, action) {
switch(action.type) {
case POSTS_REQUESTED:
return {
content: null,
isLoading: true,
error: null
}
case POSTS_RECEIVED:
return {
content: _.mapKeys(action.posts, 'id'),
isLoading: false,
error: null
}
case POSTS_REQUEST_FAILED:
return {
content: null,
isLoading: false,
error: action.error
}
default:
return state;
}
}
const rootReducer = combineReducers({
posts: postsReducer,
});
export default rootReducer;
src/sagas/index.js
import { call, put, takeEvery } from 'redux-saga/effects'
import { fetch } from '../api';
import { FETCH_POSTS } from '../actions';
export const POSTS_REQUESTED = 'posts_requested';
export const POSTS_RECEIVED = 'posts_recieved';
export const POSTS_REQUEST_FAILED = 'posts_request_failed';
export function* fetchPosts() {
yield put({ type: POSTS_REQUESTED })
const { response, error} = yield call(fetch, 'post');
if (response)
yield put({ type: POSTS_RECEIVED, posts: response })
else
yield put({ type: POSTS_REQUEST_FAILED, error })
}
export function* watchFetchPosts() {
yield takeEvery(FETCH_POSTS, fetchPosts);
}
// single entry point to start all Sagas at once
export default function* rootSaga() {
yield [
watchFetchPosts()
]
}
The output I get is
Error getting posts
{"config":{"transformRequest":{},"transformResponse":{},"timeout":0,"xsrfCookieName":"XSRF-TOKEN","xsrfHeaderName":"X-XSRF-TOKEN","maxContentLength":-1,"headers":{"Accept":"application/json,
text/plain,
/"},"method":"get","url":"http://127.0.0.1:8000/post/"},"request":{}}
When I copy paste that url into my browser, it works perfectly, so it has to be a problem with the frontend.
Why am I getting this error?
Turns out the problem was related to this
Since I'm using django-rest, I just had to add django-core-headers to my backend like in this answer

reducer not getting called even action get callled

I try to add more props to existing list i am able to fire dispatch action but reducer doesn't get trigger
i have my headercontainer.js file like
import React, { Component, PropTypes } from 'react'
import { connect } from 'react-redux'
import { fetchAccount } from 'actions/account'
import { getAccount } from 'reducers/account'
import { fetchCart } from 'actions/cart'
import { getCart } from 'reducers/cart'
//import * as cls from 'actions/cls'
import { getReadmore } from 'reducers/cls'
import * as cls from 'actions/cls'
import { fetchAuthenticityToken } from 'actions/authenticityToken'
import { getAuthenticityToken } from 'reducers/authenticityToken'
import Header from 'components/Header'
class HeaderContainer extends Component {
static propTypes = {
account: PropTypes.object,
authenticityToken: PropTypes.object,
cart: PropTypes.object,
dispatch: PropTypes.func
}
componentDidMount() {
if (typeof document !== 'undefined') {
if (!this.props.account.isFetching) {
this.props.dispatch(fetchAccount())
}
if (!this.props.authenticityToken.isFetching) {
this.props.dispatch(fetchAuthenticityToken())
}
if (!this.props.cart.isFetching) {
this.props.dispatch(fetchCart())
}
}
}
constructor(props) {
super(props);
this.state = {classToSend: true };
}
stateToRender(){
(this.state.classToSend) ? this.setState({classToSend: false}) : this.setState({classToSend: true});
}
onClickHandler(){
this.stateToRender();
let action = cls.readMore(this.state.classToSend)
this.props.dispatch(action)
// this.props.readMore(this.state.classToSend);
}
render() {
const { account, cart, authenticityToken } = this.props
if(!account || !cart) {
return false
}
return (
<div id ="cvb">
<div id="toggle-nav" className={this.state.toggleClass?'visible-xs nav-open':'visible-xs'} onClick={() => this.onClickHandler()} >
<span data-action="toggle-nav" className="action mt-menu-label">
<span className="mt-menu-bread mt-menu-bread-top">
<span className="mt-menu-bread-crust mt-menu-bread-crust-top"></span>
</span>
<span className="mt-menu-bread mt-menu-bread-middle">
<span className="mt-menu-bread-crust mt-menu-bread-crust-middle"></span>
</span>
<span className="mt-menu-bread mt-menu-bread-bottom">
<span className="mt-menu-bread-crust mt-menu-bread-crust-bottom"></span>
</span>
</span>
</div>
<Header account={account} cart={cart} />
</div>
)
}
}
const mapStateToProps = (state) => {
return {
account: getAccount(state),
cart: getCart(state),
classToSend: getReadmore(state),
authenticityToken: getAuthenticityToken(state)
}
}
export default connect(mapStateToProps)(HeaderContainer)
My cls.js reducer
export function getReadmore(state) {
console.log(state.readMore1)
console.log("are yar")
return state.readMore1
}
export function readMore1 (state="", action) {
console.log(action.type)
switch(action.type){
case READ_MORE:
return action.payload;
}
return state;
}
cls.js Action
export function readMore(class_something) {
const READ_MORE = 'READ_MORE';
console.log("--------------------------")
console.log(class_something)
return {
type: READ_MORE,
payload: class_something
};
}
Though i am able to call action cls.js file but reducer not getting trigger
can anyone help me to get out of this trouble.
My edits
my index.js in reducer folder
import { combineReducers } from 'redux'
import { reducer as form } from 'redux-form'
import { routerReducer } from 'react-router-redux'
import { currency } from './currency'
import { cart } from './cart'
import { account } from './account'
import { alerts } from './alerts'
import { login } from './login'
import { authenticityToken } from './authenticityToken'
import { products } from './products'
import { product } from './product'
const routing = routerReducer
const rootReducer = combineReducers({
form,
routing,
currency,
cart,
cls,
account,
alerts,
authenticityToken,
login,
products,
product
})
export default rootReducer
Your case in your reducer file should be "READ_MORE" (with quotations) not READ_MORE (without quotations).

Redux with React Native - unable to access property function

I have been trying to learn to This is a simple login, logout app using Redux. On pressing the Login Button from Display.js, the login_action function should be called. But an error is showing with title Cannot read property login_action of undefined. I tried logging the props in Display.js and I am able to see the functions in the logs but somehow the functions aren't being called. What is it that I'm missing or unable to find out?
Basic App :
/* App.js */
import React, {Component} from 'react';
import { createStore, applyMiddleware, combineReducers } from 'redux';
import { Provider } from 'react-redux';
import thunk from 'redux-thunk';
import * as reducers from './reducers';
import SceneContainer from './containers/SceneContainer';
const createStoreWithMiddleware = applyMiddleware(thunk)(createStore);
const reducer = combineReducers(reducers);
const store = createStoreWithMiddleware(reducer);
export default class App extends Component {
render() {
return (
<Provider store={store}>
<SceneContainer />
</Provider>
);
}
}
Container:
/* containers/SceneContainer.js */
'use strict';
import React, {Component, PropTypes} from 'react';
import Display from '../components/display';
import * as loginActions from '../actions/';
import {connect} from 'react-redux';
import {bindActionCreators} from 'redux';
class SceneContainer extends Component {
constructor(props) {
super(props);
}
render() {
const {actions} = this.props;
console.log(actions);
return (
<Display {...actions}/>
);
}
}
SceneContainer.propTypes = {
user: PropTypes.object.isRequired,
actions: PropTypes.object.isRequired
};
function mapStateToProps(state) {
return {user: state.auth.user};
}
function mapDispatchToProps(dispatch) {
console.log(loginActions);
return {
actions: bindActionCreators(loginActions, dispatch)
};
}
export default connect(mapStateToProps, mapDispatchToProps)(SceneContainer);
Component :
/* components/display.js */
import React, {Component, PropTypes} from 'react';
import {
View,
Text,
StyleSheet,
TouchableHighlight,
} from 'react-native';
class Display extends Component {
constructor(props) {
super(props);
console.log(props.login_action);
}
onLoginPress() {
this.props.login_action({
username: 'ranat',
password: 'password'
});
}
onLogoutPress() {
this.props.logout_action();
}
render() {
return (
<View>
<TouchableHighlight onPress={this.onLoginPress}>
<Text>Login</Text>
</TouchableHighlight>
<TouchableHighlight onPress={this.onLogoutPress}>
<Text>Logout</Text>
</TouchableHighlight>
</View>
);
}
}
Display.propTypes = {
logout_action: PropTypes.func.isRequired,
login_action: PropTypes.func.isRequired
};
export default Display;
Actions file :
/* actions/index.js */
import {LOGIN_ACTION, LOGOUT_ACTION, LOGIN_SUCCESS, LOGIN_FAILURE} from './actionTypes';
export var login_action = (userCredentials) => {
if(userCredentials.username === 'ranat' && userCredentials.password === 'password') {
return {
type: LOGIN_ACTION,
value: LOGIN_SUCCESS,
};
}
else {
return {
type: LOGIN_ACTION,
value: LOGIN_FAILURE,
};
}
};
export var logout_action = () => {
return {
type: LOGOUT_ACTION,
}
};
Reducers :
/* reducers/login.js */
import {LOGIN_ACTION, LOGOUT_ACTION, LOGIN_SUCCESS, LOGIN_FAILURE} from '../actions/actionTypes'
let cloneObject = (obj) => {
if(obj)
return JSON.parse(JSON.stringify(obj));
else
return {};
}
const initialState = {
user: {
loggedIn: false,
},
};
const auth = (state = initialState, action = {}) => {
switch(action.type) {
case LOGIN_ACTION: {
if(action.value === LOGIN_SUCCESS) {
return {
...state,
user: {
loggedIn: true
}
};
}else {
return {
...state,
user: {
loggedIn: false
}
};
}
}
case LOGOUT_ACTION: {
if(action.value === LOGIN_SUCCESS) {
return {
...state,
user: {
loggedIn: false
}
};
}else {
return state;
}
}
default: {
return state || initialState;
}
}
}
export default auth;
/* reducers/index.js */
import { combineReducers } from 'redux';
import auth from './login';
export {
auth,
};
Change onPress={this.onLoginPress} to onPress={this.onLoginPress.bind(this}.
Do the same for onPress={this.onLogoutPress} also.

Categories