0

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 ?

  • 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?

  • 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?

  • Fourth question: When using redux where should i put async data and make component waits these data before re-render?

     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 || false;
    default:
      return state;
  }
}

Thank you, Any help would really be appreciated.

Dodz
  • 187
  • 1
  • 6
  • 14

2 Answers2

0

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){
        case 'FETCH_USER': return {...state,payload:action.payload}|| false;
        default:
          return state;
      }
    }

This is just the basic outline and you should be able to take it from here.

Vijay Venugopal Menon
  • 1,510
  • 1
  • 14
  • 20
  • 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 '18 at 18:10
  • @Dodz, i have updated my answer with the code. Please check and let me know for any queries – Vijay Venugopal Menon Aug 10 '18 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 '18 at 18:41
  • You can have a parent component for header,profile and other components. something like a . All the other components would be the child of this component and call the fetchUser() in . Then it wont be called multiple times. – Vijay Venugopal Menon Aug 10 '18 at 18:43
0

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.

SamiNami
  • 21
  • 5