In this post, we will see how an action can be dispatched using Redux on login, and set the app state accordingly. Assuming familiarity with React Native and Redux concepts We have the following Login component to begin with : React, { useState } ; { View, Button, Text } ; CustomButton ; InputField ; { styles } ; Login = { [username, setUsername] = useState( ); [password, setPassword] = useState( ); ( <InputField placeholder='Enter username' value={username} onChangeText={(text) => setUsername(text)} /> <InputField placeholder='Enter password' secureTextEntry={true} value={password} onChangeText={(text) => setPassword(text)} /> <CustomButton title='Sign In' onPress={() => } /> ); }; export default Login; import from 'react' import from 'react-native' import from '../../components/CustomButton' import from '../../components/InputField' import from './style' const ( ) => props // remove these initial assignments after testing const '' const '' return < > View Right now it doesn’t do anything, it’s just barebones UI. To make it “react” to user action we should update the paramter in the button. onPress SignIn <CustomButton title= onPress={() => } /> 'Sign In' We use here, so pressing the button should dispatch and action to the reducer which should in turn update the overall app's state. redux For sake of simplicity, all redux code is placed in a ‘ ’ folder, while the components are in ‘ ’. redux src/components/<ComponentName>/index.js This is how our folder looks like. redux ├── actions.js ├── actionTypes.js ├── initialState.js ├── reducer.js └── store.js redux Let’s set as follows. These are all the fields that our login API will return (yours may differ). initialState and in are flags that we will set on our own (these are not part of API response) userId isLogged initialState = { : , : , : , : , : , : , }; export const isLoggedIn false userId '' token '' refreshToken '' expiresOn '' data '' Define action type in actionTypes.js SET_LOGIN_STATE = export const "SET_LOGIN_STATE" Let’s now create our in loginReducer reducer.js { initialState } ; * t ; loginReducer = { (action.type) { t.SET_LOGIN_STATE: { ...state, ...action.payload, isLoggedIn: , }; : state; } }; import from './initialState' import as from './actionTypes' export const ( ) => state = initialState, action switch case return // this is what we expect to get back from API call and login page input true // we set this as true on login default return We can now generate our redux store using all the available information and thunk as middle-ware to handle API calls. thunkMiddleware ; { createStore, combineReducers, applyMiddleware } ; { composeWithDevTools } ; { loginReducer } ; rootReducer = combineReducers({ : loginReducer, }); store = createStore( rootReducer, composeWithDevTools(applyMiddleware(thunkMiddleware)) ); import from 'redux-thunk' import from 'redux' import from 'redux-devtools-extension/developmentOnly' // this is for debugging with React-Native-Debugger, you may leave it out import from './reducer' const loginReducer export const We have these things in place but we still have not figured how to set the state from the Login component. For this we need to define some actions in actions.js What we are looking at is a function that can call the login API and return the result back to us. Something like : fetch(LoginUrl, { : , : { : , : , }, : .stringify(loginInput), }) .then() ................... return method 'POST' headers Accept 'application/json' 'Content-Type' 'application/json' body JSON But we also need to ensure that the action is “connected” to the “reducer” in order to update the state or store. redux Since API call is considered unpredictable, it should not dispatch the action object directly to reducer, but through a helper. Dispatching action can return only an Object. If it returns a promise the app will break. We need to make sure of this. In : actions.js * t ; { LoginUrl } ; setLoginState = { { : t.SET_LOGIN_STATE, : loginData, }; }; import as from './actionTypes' import from '../constants/Api' // this is what our action should look like which dispatches the "payload" to reducer const ( ) => loginData return type payload To fetch this in the action above, we create another function using the fetch operation discussed above: loginData { Alert } ; login = { { username, password } = loginInput; { fetch(LoginUrl, { : , : { Accept: , : , }, : .stringify(loginInput), }) .then( response.json()) .then( { (json.msg === ) { dispatch(setLoginState({ ...json, : username })); } { Alert.alert( , ); } }) .catch( { Alert.alert( , ); .log(err); }); }; }; import from 'react-native' // to show alerts in app export const ( ) => loginInput const return ( ) => dispatch // don't forget to use dispatch here! return method 'POST' headers // these could be different for your API call 'application/json' 'Content-Type' 'application/json' body JSON ( ) => response ( ) => json if 'success' // response success checking logic could differ userId // our action is called here else 'Login Failed' 'Username or Password is incorrect' ( ) => err 'Login Failed' 'Some error occured, please retry' console You can see how our action is dispatched from this function, which in turn will return a payload object to the reducer in order to perform state update. Only thing remaining now is connecting this function to the UI. Let’s go back to our component in the Submit button section and specify Login onPress { useDispatch } ; { login } ; ............... <CustomButton title= onPress={() => useDispatch(login({ : username, : password }))} /> ............... import from 'react-redux' import from '../../redux/actions' 'Sign In' 'username' 'password' Since we are using here, all our functions should ideally be in form of some action, which will be caught in the middleware first and then passed on appropriately to reducer. redux redux-thunk On successful login, the values will all be populated. On failure, an alert will show up stating error. initialState I hope this was helpful & informative :) Also published at https://dev.to/skd1993/creating-a-simple-login-function-with-redux-and-thunk-in-react-native-33ib