React Redux not displaying the data when trying to dispatch (Firestore)

Viewed 52

I'm trying to use React Redux on my application. I will be building something like instagram, so the scale of the application is going to be big. I have implement redux correctly (I believe) although I'm not getting the fetch result from firestore on the dispatch function, if I insert the same code before the return it works.
action/index.ts:

import { db, auth } from '../../services/firebase';
import { USER_STATE_CHANGE } from '../constants';

export function fetchUser() {
  return (dispatch: any) => {
    db.collection('users')
      .doc(auth.currentUser!.uid)
      .get()
      .then((snapshot) => {
        if (snapshot.exists) {
console.log(snapshot)
          dispatch({
            type: USER_STATE_CHANGE,
            payload: snapshot.data(),
          });
        }
      });
  };
}

constants/index.ts:

export const USER_STATE_CHANGE = 'USER_STATE_CHANGE';

reducers/index.ts:

import { combineReducers } from 'redux';
import { user } from './user';

const Reducers = combineReducers({
  userState: user,
});

export default Reducers;

reducers/user.ts:

const initialState = {
  currentUser: null,
};

export const user = (state = initialState, action: any) => {
  return {
    ...state,
    currentUser: action.currentUser,
  };
};

App.tsx:

// Redux
import { Provider } from 'react-redux';
import { createStore, applyMiddleware } from 'redux';
import rootReducer from './src/redux/reducers';
import thunk from 'redux-thunk';

const store = createStore(rootReducer, applyMiddleware(thunk));

export default function App() {
  if (!fontsLoaded) return <></>;

  return (
    <ThemeProvider theme={theme}>
      <Provider store={store}>
        <Main />
      </Provider>
      <ToastMessage />
    </ThemeProvider>
  );
}

Main.tsx:

import React, { useEffect, useState } from 'react';
import { NavigationContainer } from '@react-navigation/native';
import { StatusBar } from 'expo-status-bar';
import { AuthRoutes } from './routes/auth.routes';
import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';
import { fetchUser } from './redux/actions';
import { auth } from './services/firebase';

function Main() {
  const [isAuthenticated, setIsAuthenticated] = useState(false);

  useEffect(() => {
    fetchUser();

    auth.onAuthStateChanged((user) => {
      if (user) setIsAuthenticated(true);
    });
  }, []);

  return (
    <NavigationContainer>
      <AuthRoutes isAuthenticated={isAuthenticated} setIsAuthenticated={setIsAuthenticated} />
      <StatusBar style="auto" />
    </NavigationContainer>
  );
}

const mapDispatchProps = (dispatch: any) => bindActionCreators({ fetchUser }, dispatch);

export default connect(null, mapDispatchProps)(Main);

The fetchUser() is called here, and should log the data from firestore, although I don't get any data logged.
The function is beeing called: enter image description here

2 Answers

on reducer/user.ts

Have you try to do this:

const initialState = {
  currentUser: null,
};

export const user = (state = initialState, action: any) => {
  return {
    ...state,
    currentUser: action.payload,
  };
};

Replace this

export const user = (state = initialState, action: any) => {
  return {
    ...state,
    currentUser: action.currentUser,
  };
};

With this

export const user = (state = initialState, action: any) => {
  return {
    ...state,
    currentUser: action.payload,
  };
};

Because you are setting data in payload but you are accessing from currentUser which empty. Either replace payload with currentUser in useDispatch or replace currentUser with payload in reducer.

Related