I have a question about redux
.
Now, I'm building my mobile app following redux advanced tutorial.
The tutorial says that you have to create 3 actions each 1 function so I have created 3 actions for sign-in function like below:
requestSignIn
requestSignInSuccess
requestSignInFailure
However, I don't understand where the app should call them from.
Now, in my app, the app calls requestSignInSuccess
and requestSignInFailure
in requestSignIn
.
This is my action code:
export const REQUEST_SIGN_IN = 'REQUEST_SIGN_IN';
export const REQUEST_SIGN_IN_FAILURE = 'REQUEST_SIGN_IN_FAILURE';
export const REQUEST_SIGN_IN_SUCCESS = 'REQUEST_SIGN_IN_SUCCESS';
import firebase from 'react-native-firebase';
export function requestSignIn() {
// start sign in function
firebase.auth().signInWithEmailAndPassword(EMAIL, PASSWORD)
.then(response => {
// success, so call requestSignInSuccess() to change state
requestSignInSuccess(response.user);
})
.catch(error => {
// fail, so call requestSignInFailure() to change state
requestSignInFailure(error);
})
}
function requestSignInSuccess(user) {
// save user info into state in reducer
return {
type: 'REQUEST_SIGN_IN_SUCCESS'
payload: user
}
}
function requestSignInFailure(error) {
// save error message into state in reducer
return {
type: 'REQUEST_SIGN_IN_FAILURE'
payload: error
}
}
[Questions]
redux
tutorial correctly? (The app calls requestSignInFailure
and requestSignInSuccess
in requestSignIn
function, is it good?)isLoading
flag into state, which action should change the flag?Let me try to answer one by one your questions.
Am I following the
redux
tutorial correctly?
Yes, you are on the right track, just few steps missing. The below explanation is for class based components.
Technically if you created actions - just like above in your question - then what you need to do is dispatching them in the component in order to use.
mapDispatchToProps
.requestSignIn
action - with the Redux
store.mapDispatchToProps
to connect as the second parameter.Please find the following example below:
import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';
// ... other imports
class YourComponent extends React.Component {
constructor (props) {
super(props);
}
// ... component code
// ... obviously this is just an example component for representation
render() {
return (
<>
<a onClick={props.requestSignIn()}>Request Sign In</a>
</>
)
}
}
const mapDispatchToProps = dispatch => {
return bindActionCreators({ requestSignIn }, dispatch);
};
export default connect(null, mapDispatchToProps)(YourComponent);
If I want the app to have
isLoading
flag into state, which action should change the flag?
I would create in the reducer a new property called isLoading
just like below:
const initialState = {
isLoading: false,
};
export default (state=initialState, action) => {
switch(action.type) {
case 'ENABLE_LOADING':
return {
...state,
isLoading: true,
};
case 'REQUEST_SIGN_IN_SUCCESS':
return {
...state,
isLoading: false,
};
case 'REQUEST_SIGN_IN_FAILURE':
return {
...state,
isLoading: false,
};
// ... other actions
}
}
In your requestSignIn
action need to trigger ENABLE_LOADING
once you start fetching the data one line before firebase.auth().signInWithEmailAndPassword(EMAIL, PASSWORD)
then it will hopefully work for you. Just like how you did with REQUEST_SIGN_IN_SUCCESS
and REQUEST_SIGN_IN_FAILURE
.
To access the reducer's properties you need to use mapStateToProps
further.
In functional component case you need to use useDispatch
to call the created actions:
This hook returns a reference to the dispatch function from the Redux store. You may use it to dispatch actions as needed.
And to access the data from the store there is a hook called useSelector
:
Allows you to extract data from the Redux store state, using a selector function.
Quick summary:
If you are looking for a fully working example with useSelector
and useDispatch
in a functional component then take a look at this git repository:
https://github.com/norbitrial/react-redux-loading-data-example
In the repository you will find a nice representation of a fake API call which loads data into a table with a loader indicator, just like what you need from your question.
In case of further interest in more details please find the below links which are pretty useful:
useDispatch()
for functional componentuseSelector()
for functional componentI hope this helps, let me know if you need further clarification.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With