Handling rendering async data when using redux?
Clash Royale CLAN TAG#URR8PPP
Handling rendering async data when using redux?
I am confused a little bit about the idea of re-rendering.
First question: In React
without redux
do changing in components props
trigger re-render ?
React
redux
props
Second question: How to handle async data when using redux, in react without redux
after AJAX
request i used to put setState
inside componentDidMount()
so changing in state
causes component to re-render. Using redux i read that the only way you must use connect
helper in order to make component re-render is that true?
react without redux
AJAX
setState
componentDidMount()
state
connect
Third question: In the following code (Component that returns navbar
with child elements that depends whether the user is authenticated or not) I triggered unexpected behavior sometimes the navbar
returns Loading...
and stops forever. Other times it returns Loading...
at first then automatically changed to User Profile
if user logged in or Sign Up
if not. why is that happening?
navbar
navbar
Loading...
Loading...
User Profile
Sign Up
Fourth question: When using redux
where should i put async data and make component waits these data before re-render?
redux
class Header extends Component
renderComponent()
switch(this.props.auth)
case null : return <li>Loading...</li>;
case false: return <li><a>Log In</a></li>;
default: return <li><a>User Profile<a/></li>
render()
return(
<nav>
<ul>
this.renderComponent()
</ul>
</nav>
)
const mapStateToProps = (auth) =>
return
auth
export default connect(mapStateToProps)(Header);
Action Creator
export const fetchUser = ()=>
return async (dispatch) =>
const res = await axios.get('/api/currentuser');
dispatch(
type: FETCH_USER,
payload: res.data
);
;
Reducer
export default (state = null, action) =>
switch(action.type)
case 'FETCH_USER': return action.payload
Thank you, Any help would really be appreciated.
2 Answers
2
4
In the redux store. If there is any change to the data in the redux store. All mounted components that listen to the store will rerender.
I've used Redux Thunk for async code: https://github.com/reduxjs/redux-thunk. It allows you to return promises in your action creators.
So the data flow works something like this: Redux store is initialized with empty values. This causes the page to render the first time. Then you have async calls to your backend to fetch the data. As the redux store is populated with the data it causes the site to rerender.
First Question - No, changing props won't rerender - Why can't I update props in react.js?
Second Question - Yes, you have to use the connect helper and use middlewares(redux-thunk, redux-saga), which can be used for async calls . Their documentation has all the details - https://github.com/reduxjs/redux-thunk & https://github.com/redux-saga/redux-saga
Third Question - We will need to see more code to answer. Need to know how "auth" is set.
Fourth Question - You should use a middleware as explained in the second question. The middleware will take care of getting the data and re-rendering.
Code
Note: Add a mapDispatchToProps and call the function in your compponentDidMount().
Your reducer and action creators look correct. Just one observation in your reducer explained below:
import * as actions from '<action creator file path>';
class Header extends Component
componentDidMount()
this.props.fetchUser();
renderComponent()
switch(this.props.auth)
case null : return <li>Loading...</li>;
case false: return <li><a>Log In</a></li>;
default: return <li><a>User Profile<a/></li>
render()
return(
<nav>
<ul>
this.renderComponent()
</ul>
</nav>
)
const mapStateToProps = (auth) =>
return
auth
const mapDispatchToprops = (dispatch) =>
return
fetchUser = () => dispatch(actions.fetchUser())
export default connect(mapStateToProps,mapDispatchToProps)(Header);
Reducer
const initialState =
payload:null,
...<other states>
export default (state = null, action) =>
switch(action.type) false;
default:
return state;
This is just the basic outline and you should be able to take it from here.
I updated the code with reducer and action creator, and please could you clarify your answer on the fourth question what middlewares for example?
– Dodz
Aug 10 at 18:10
@Dodz, i have updated my answer with the code. Please check and let me know for any queries
– Vijay Menon
Aug 10 at 18:32
Its a header component that is used in every page, which means i will reach a point that
fetchUser()
is called multiple times. if a component also rely on fetchUser()
for example Profile
component . So it will be called twice one from profile and other from header, would it be okay ?– Dodz
Aug 10 at 18:41
fetchUser()
fetchUser()
Profile
You can have a parent component for header,profile and other components. something like a <Layout /> . All the other components would be the child of this component and call the fetchUser() in <Layout />. Then it wont be called multiple times.
– Vijay Menon
Aug 10 at 18:43
@Dodz, Were you able to get this working?
– Vijay Menon
Aug 10 at 19:16
By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.
for managing async data you should use a library like redux-saga.
– Prabhu Murthy
Aug 10 at 17:57