0
votes

I'm trying to do auth sign-out with react-native and am experiencing an issue where I want to reset the state of the redux store but, because I am using react-navigation, I have a bunch of redux-connected screens that are still mounted that re-render when the state tree is reset to it's initialState causing a bunch of exception errors. I tried to unmount them on sign-out with a react-navigation reset which redirects the user to the signup/login screen but I have no way of knowing when these screens are actually unmounted in order to call the RESET_STATE action. Initially I was dispatching the action via saga.

sagas/logout.js

import { LOGOUT, RESET_STATE } from 'Actions/user';

// clear localstorage once user logs out.
const clearData = function* clearData(action) {
  AsyncStorage.removeItem('user');
  
  yield put(
    NavigationActions.reset({
      index: 0, 
      actions: [ 
        NavigationActions.navigate({ routeName: 'SignedOut' })
      ],
    })
  );
  // causes re-renders, screens still mounted
  yield put({type: RESET_STATE});
}

export default function* logoutSaga () {
  yield all([
    yield takeEvery(LOGOUT, clearData),
  ]);
}

I also tried to reset once user reaches the SignedOut screen in it's componentDidMount cycle but unfortunately the screens unmount at some point well after componentDidMount is triggered:

screens/SignedOut.js

import { resetState } from 'Actions/user';
import ActionButton from 'Components/FormElements/ActionButton';

class SignedOut extends Component {
  // screens are still mounted, causing screens from
  // previous screens to throw exception errors
  componentDidMount() {
    this.props.dispatch(resetState());
  }

  componentWillUnmount() {
    // never called
  }

  handleSignup = () => {
    this.props.navigation.navigate('Signup');
  }

  handleLogin = () => {
    this.props.navigation.navigate('Login');
  }

  render() {
    return(
      <Container>
        <ActionButton
          text="Sign Up"
          handleButtonPress={this.handleSignup}
        />
        <ActionButton
          text="Log In"
          handleButtonPress={this.handleLogin}
        />
      </Container>
    );
  }
}

export default connect()(SignedOut);

My question is, can anyone think of a way to reset state of redux store after all of my screens have finally unmounted by the react-navigation reset action?

3

3 Answers

1
votes

The issue is you're using navigate to navigate to the login/signup screen which leaves all your other components mounted, you should probably use back or reset to unmount all the components and show the login screen.

1
votes

After thinking about this for a long time, I figured out that maybe I should have been focusing on the errors thrown instead of why I was getting errors. (I did learn a lot though).

Although figuring out how to listen for when all the screens are completely unmounted after calling a reset would have been super helpful, it would have just been a shortcut to bypass the real issue, the initialState for certain branches of my redux state was wrong. After correcting this no more errors, no matter when react-navigation decides to unmount the old screens.

0
votes

As i have no idea how ur state looks like, which is always the issue here, why not try to use componentWillUnmount on all those components, to set a state variable and check that when you want to reset navigation?