React components unmount and remount when dispatching redux action in lifecycle methods

This occurs with React + Redux Saga application my team is working on

We buy the React Isomorphic theme from Themeforest which bundles the Redux, Saga, and React Router V.4. We are now working on top of it.

I have been using React for a while but new to Redux and never experienced with such behavior. The problem is that whenever I dispatch an action, the component unmounts and remounts as the state changes

Okay, what I am doing is to fetch some user data from the API but. So this is how I come up with the following action & reducer

// Actions.js

const UserActions = {
    FETCH_USER_REQUEST: 'FETCH_USER_REQUEST',
    FETCH_USER_SUCCESS: 'FETCH_USER_SUCCESS',
    fetch_users: () => {
        return {
            type: UserActions.FETCH_USER_REQUEST
        }
    }
}

export default UserActions;

And the reducer

// Reducer.js
export default function UserReducer(state = initialState, action) {
    switch (action.type) {
        case 'REQUEST_USER_SUCCESS':
            return state.set('user_list', action.user_list);
        default:
            return state;
    }
}

With Redux Saga, the middleware is created to handle async actions. This is how it looks

// Saga.js
import { all, takeEvery, call, put, fork } from 'redux-saga/effects';
import {get, post} from 'axios';

export function fetchUser() {
    return get('https://mockapi.testapp.dev/users')
    .then(response => {
         return response.data;
    }).catch(error => {
         return error.data
    });
}

export function* fetchUserRequest() {
    yield takeEvery('FETCH_USER_REQUEST', function*() {
        const resp = yield call(fetchUser);
        yield put({
            action: 'FETCH_USER_SUCCESS',
            user_list: resp
        });
    });
}

export default function* rootSaga() {
   yield all([
      fork(fetchUserRequest)
   ]);
}

Now I implement the code in my component like this

// App.js
import React, {Component} from 'react';
import {connect} from 'react-redux';
import UserActions from './actions/UserAction';

const mapStateToProps = (state, ownProps) => {
    return {
        userList: state.User.get('user_list')
    }
}

const mapDispatchToProps = dispatch => {
    return {
        fetchUser: () => dispatch(UserActions.fetch_users())
    }
}

class App extends Component {
    componentDidMount() {
        this.props.fetchUser();
    }

    render() {
        // ... The rest of the rendering processes
    }
}

export default connect(mapStateToProps, mapDispatchToProps)(App);

Now that you can see, with the behavior mentioned prior to this. Dispatching an action via this.props.fetchUser() cause the state to change but what I don't expect is that the component shouldn't unmount and remount because once it does so, an infinite loop occurs because the componentDidMount runs over and over and state also changes accordingly.

What I expect is to fetch the data from the API once the component mounts without remounting itself once the state changes for any reason because the theme we purchased is equipped with other base components which make use of Redux-saga to handle state and async actions. For example, the collapsable sidebar triggers a dispatch which changes the state that controls its bahavior once the users click on the it. Currently, once it does that my current component immediately unmounts unexpectedly.

Is there any possible way to solve such a problem or this is the default behavior of Redux?

Upvotes: 12

Views: 4592

Answers (1)

Pen Abdoul Guira
Pen Abdoul Guira

Reputation: 1

using StrictMode in your application : when the component is first mounted: strictmode will simulate mounting, unmounting and remounting to detect any hidden bug in the code. It's a development tool to try to help you find bugs in your code. like unclean side effects in the use effects.It will run the useEffects twice. It will also detect deprecated code and show you a warning in the console.

It's a development tool that helps you find bugs in your code related to double rendering or forgetting to clean up your side effects.

You may wanna try uncommenting strictMode if you are using it. Let's see if it will solve the issue

Upvotes: 0

Related Questions