Felipe Font
Felipe Font

Reputation: 113

How to listen for redux-state change from the app.js component (root)

How to listen for redux-state change from the app.js component (root)?

Hi there,

I want to trigger an async function that writes in Firestore DB when exist an specific object in state.

I thought the way of doing this it’s placing the logic in the root app component (index.js) because I need to trigger it if the condition is meet no matter which screen component is open.

this is my appComponent:

import { Provider } from 'react-redux';
import configureStore from './store/configureStore';

const store = configureStore();

export default class App extends React.Component {
    render() {

    //navigators were removed for code brevity and component imports

    const MainNavigator = TabNavigator({
      welcome: { screen: WelcomeScreen },
      login: { screen: LoginScreen },
      signup: { screen: RegisterScreen },
      main: { screen: AppNavigator },
  }, {
    navigationOptions: {
      tabBarVisible: false
    },
  });

    return (
      <Provider store={store}>
        <View style={{ flex: 1 }}>
          {/*<ModalAlerta />*/}
          <StatusBar hidden />
          <MainNavigator />
        </View>
      </Provider>
    );
  }
}

---This fragment got updated:

This is the configureStore() im importing:

import { createStore, applyMiddleware, compose } from 'redux';
import thunk from 'redux-thunk';
import reducers from './reducers';

let composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose;

  function configureStore(initialState) {
    const store = createStore(
      reducers,
      initialState,
      composeEnhancers(applyMiddleware(thunk)));

    return store;
  }

export default configureStore;

--- End of edition

I though that with componentWillReceiveProps() could do the trick, but it doesn’t get called. As I didn’t saw any log of the lifecycle method I realized that state and props are not bind here as is in the subcomponents (reason to not being invoqued) so I tried to connect the app component as any other component using connect().

When I tried to do so I did it this way:

import { Provider } from 'react-redux';

//I removed the export statement from here to bottom
class App extends React.Component {

    componentWillReceiveProps(nextProps) {
        //Did not get triggered
        console.log(nextProps);
    }
    render() {

    //navigators were removed for code brevity and component imports

    const MainNavigator = TabNavigator({
      welcome: { screen: WelcomeScreen },
      login: { screen: LoginScreen },
      signup: { screen: RegisterScreen },
      main: { screen: AppNavigator },
  }, {
    navigationOptions: {
      tabBarVisible: false
    },
  });

    return (
      <Provider store={store}>
        <View style={{ flex: 1 }}>
          {/*<ModalAlerta />*/}
          <StatusBar hidden />
          <MainNavigator />
        </View>
      </Provider>
    );
  }
}

const mapStateToProps = state => {
  return {
    factura: state.facturacion.factura[0]
  };
};

export default connect(mapStateToProps, { })(App);

but this is the error I get:

Error: Invariant Violation: Could not find "store" in either the context or props of "Connect(App)". Either wrap the root component in a <Provider>, or explicitly pass "store" as a prop to "Connect(App)".

I’ve been searching how to explicitly pass the store as prop to connect but I cant make it work yet.

Can somebody bring some light to this newbie?

Upvotes: 2

Views: 1657

Answers (1)

adam.k
adam.k

Reputation: 632

You have to use createStore() to first create your store before passing it through. Also as the error states you need to "wrap the root component (App) in a Provider..."

In index.js make sure you have something like this.

...
import {createStore} from 'redux'
import {Provider} from 'react-redux'

import App from './App'
import reducer from './reducer'


const store = createStore(reducer)

document.addEventListener('DOMContentLoaded', () => {
   render(
      <Provider store={store}>
        <App />
      </Provider>,
      document.getElementById('app')
    )
 })

Upvotes: 1

Related Questions