How to access redux state in App.js (React-Native)

I am a beginner in react native and redux and working on it for the first time. I am not sure how to use the returned value in store.getState() in the App.js file.

console.ignoredYellowBox = ["Remote debugger"];
import { YellowBox } from "react-native";
YellowBox.ignoreWarnings([
  "Unrecognized WebSocket connection option(s) `agent`, `perMessageDeflate`, `pfx`, `key`, `passphrase`, `cert`, `ca`, `ciphers`, `rejectUnauthorized`. Did you mean to put these under `headers`?",
]);
import React, { Component } from "react";
import { StyleSheet, Text, View, AsyncStorage } from "react-native";
import * as Font from "expo-font";
import { AppLoading } from "expo";
import AppNavigation from "./navigation/AppNavigator";
import { setNavigator } from "./navigationRef";
import userReducer from "./reducers/userReducer";
import chatReducer from "./reducers/chatReducer";
import { Provider } from "react-redux";
import { createStore, applyMiddleware, combineReducers } from "redux";
import ReduxThunk from 'redux-thunk';
import createSocketIoMiddleware from "redux-socket.io";
import io from "socket.io-client";

const store = createStore(combineReducers({userReducer, chatReducer}), applyMiddleware(ReduxThunk));
class App extends Component {
  constructor(props) {
    super(props);
    console.log(props);
    this.state = {
      fontLoaded: false,
    };
  }
  async componentWillMount(){
    const response = await(store.getState().userReducer.token)
    console.log("Response:", response)
  }
  render() {

    const fetchFont = () => {
      return Font.loadAsync({
        "raleway-bold": require("./assets/fonts/Raleway-Bold.ttf"),
        ralewayBold: require("./assets/fonts/Raleway-Bold.ttf"),
        "roboto-regular": require("./assets/fonts/Roboto-Regular.ttf"),
        robotoRegular: require("./assets/fonts/Roboto-Regular.ttf"),
        Roboto_medium: require("./assets/fonts/Roboto-Regular.ttf"),
      });
    };
    if (!this.state.fontLoaded) {
      return (
        <AppLoading
          startAsync={fetchFont}
          onFinish={() => this.setState({ fontLoaded: true })}
          onError={(err) => {
            console.log(err);
          }}
        />
      );
    }
    return (
      <Provider store={store}>
        <AppNavigation
          ref={(navigator) => {
            setNavigator(navigator);
          }}
        />
      </Provider>
    );
  }
}
const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: "#fff",
    alignItems: "center",
    justifyContent: "center",
  },
});

export default App;

I want to get access to redux state from here to access the token stored there. After referring to few posts, I tried using store.getState() method but when I console.log it, I get null

Upvotes: 1

Views: 4921

Answers (2)

Rasheed Qureshi
Rasheed Qureshi

Reputation: 1273

Brief Details

example code of your App.js call

<Provider store={store}>
 <App />
</Provider>

Now we will try to dispatch and getState from the store without connect of react-redux

through this approach, we will not have the need of mapStateToProps and mapDispatchToProps

As we already import our store in App.js. e.g

import store from "./redux/store";

first, we dispatch some action from App.js through store directly.

like we have some action in our epic folder like this

import {someAction} from './redux/epics/fetch-some-epic'

Now this is our dispatch action from App.js

    store.dispatch(someAction())

and this is the state that we can get from store in our App.js

store.getState().someState

Thanks and regards

Upvotes: 1

pachonjcl
pachonjcl

Reputation: 741

You should not use directly the reference to store, instead you should use the method connect to connect your component, in this case App to the store as follows:

import { connect } from 'react-redux';
...
class App extends Component {
   constructor(props) {
     console.log(props.token);//you will get here the token
     ...
   }
   ...
}
....
const mapStateToProps = (state) => {
  return {
    token: state.userReducer.token,
  };
};
const mapDispatchToProps = (dispatch) => {
  return {//You should put here your dispatch methods later
  };
};

export default connect(mapStateToProps, mapDispatchToProps)(App)

--------------- Edited -----------

I just noticed that you are trying to access the store inside the App component, but since you are defining the Provider in the App.render method you should do one of two things: 1) You should add the <Provider store={store}> one level above App. in the index.

<Provider store={store}>
 <App />
</Provider>

In this case, App render should not contain the Provider anymore.

2) You should move the logic of using the token to a level below of App and use the connect on the component below:

class IntermediateComponent extends Component {
  constructor(props) {
     console.log(props.token);//you will get here the token
     ...
  }
}
const mapStateToProps = (state) => {
  return {
    token: state.userReducer.token,
  };
};
const mapDispatchToProps = (dispatch) => {
  return {//You should put here your dispatch methods later
  };
};
const ConnectedIntermediateComponent = connect(mapStateToProps, mapDispatchToProps)(IntermediateComponent)

class App extends Component {
  ...
  render() {
    <Provider store={store}>
      <ConnectedIntermediateComponent>
        <AppNavigation
          ref={(navigator) => {
            setNavigator(navigator);
          }}
        />
      </ConnectedIntermediateComponent>
    </Provider>
  }
}

export default App;

Note that in 2) App is no longer connected.

Upvotes: 1

Related Questions