Handling rendering async data when using redux?

The name of the pictureThe name of the pictureThe name of the pictureClash 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.





for managing async data you should use a library like redux-saga.
– Prabhu Murthy
Aug 10 at 17:57





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.

Popular posts from this blog

Firebase Auth - with Email and Password - Check user already registered

Dynamically update html content plain JS

How to determine optimal route across keyboard