inProgress-team / inProgress-team/react-native-meteor
createContainer not re-running with variable change (react-navigation, redux + react-native-meteor)
- Dominant language
- JavaScript
- Stars
- 688
- Forks
- 200
- PR merge metrics
- No merged PRs in 30d
Description
I'm trying to use react-navigation with redux (and react-native-meteor). This is my current setup which follows [react-navigation](https://reactnavigation.org/docs/guides/redux) advice. My entry point file is below:
src/index.js
```
import React from 'react';
import Meteor, { createContainer } from 'react-native-meteor';
import { Loading } from './components/common';
import { addNavigationHelpers } from 'react-navigation';
import { Provider, connect } from "react-redux";
import getStore from "./store";
import Routes from "./routes";
import * as actions from './actions';
//connect to meteor
Meteor.connect('ws://localhost:3000/websocket');
//create nav reducer
const navReducer = (state, action) => {
const newState = Routes.router.getStateForAction(action, state);
return newState || state;
};
const mapStateToProps = (state) => {
return {
nav: state.nav,
bizStages: state.bizStages,
categories: state.categories,
selectedLocation: state.selectedLocation
}
};
// connect Routes Component with redux, remember you need babelrc with "transform-decorators-legacy" to use decorators
@connect(mapStateToProps)
class RoutesWithNavigationState extends React.Component {
render() {
return (
);
}
}
// create store and then rest of this file is similar to setup in Spencer's react-native-meteor-boilerplace: https://github.com/spencercarli/react-native-meteor-boilerplate
const store = getStore(navReducer);
const App = (props) => {
return (
{props.status.connected === false || props.loggingIn
?
:
}
);
}
App.propTypes = {
status: React.PropTypes.object,
user: React.PropTypes.object,
loggingIn: React.PropTypes.bool,
};
export default createContainer(() => {
return {
status: Meteor.status(),
user: Meteor.user(),
loggingIn: Meteor.loggingIn(),
};
}, App);
```
store.js
```
import { createStore, applyMiddleware } from "redux";
import thunk from "redux-thunk";
import getRootReducer from "./reducers";
const getStore = (navReducer) => {
const store = createStore( getRootReducer(navReducer), undefined, applyMiddleware(thunk) );
return store;
}
export default getStore;
```
reducers/index.js
```
import { combineReducers } from "redux";
const BizStageReducer = (state=['idea', 'early', 'existing'], action) => {
return state;
};
const CategoriesReducer = (state=['support', 'finance', 'incentives'], action) => {
return state;
};
const LocationsReducer = (state=null, action) => {
console.log(action)
switch(action.type) {
case 'select_location':
return state = action.payload;
default:
return state;
}
};
const getRootReducer = (navReducer) => {
return combineReducers({
nav: navReducer,
bizStages: BizStageReducer,
categories: CategoriesReducer,
selectedLocation: LocationsReducer
});
};
export default getRootReducer;
```
There is no login right now. My initial screen is just a list (``, which you can see below). At the top of the page there is a picker (``) that allows you to select a location. It runs a redux action. That action runs correctly, and `` from `src/index.js` reruns with new props, but my createContainer that wraps MainScreen (see below) is not re-run...
So I'm not 100% sure how to set this up. It'd be great if all actions and redux store values can just be dropped down via the navigation prop instead of sprinkling @connect everywhere I could just have it in `src/index.js`... but child components are not updating when properties on the navigation object change.
Should I use @connect on createContainer to get it to work? am I just missing some redux-related thing? Its getting a little crazy between all these HOCs...(1) hoistNonReactStatic so I can use static in my class, (2) createContainer from react-native-meteor and now I'm wondering if I have to wrap it again in @connect so that I have access to the redux variables in createContainer?
```
import React from 'react';
import Meteor, { createContainer } from 'react-native-meteor';
import { Image, TouchableHighlight, View, ListView } from 'react-native';
import { Container, Content, Grid, Picker, Col, Card, CardItem, Left, Body, Text, Button, Icon, Right } from 'native-base';
import hoistNonReactStatic from 'hoist-non-react-statics';
import { Loading } from '../../components/common';
import { connect } from "react-redux";
import * as actions from '../../actions';
import { ResourceCard from './ResourceCard'
import { LocationSelector } from './LocationSelector'
class MainScreen extends React.Component {
static navigationOptions = {
title: 'Home',
tabBar: { label: 'Home' }
};
render(){
let { navigation, items, resourceItemsReady } = this.props;
let { navigate, dispatch } = navigation;
let ds = new ListView.DataSource({rowHasChanged: (r1, r2) => r1 !== r2});
if (!resourceItemsReady) {
return (
);
}
return (
Show me resources near...
dispatch({ type: 'select_location', payload: value})}
/>
}
/>
);
}
}
const container = createContainer(params => {
let resourceItemsSub = Meteor.subscribe('ResourceItems.searchResults'); //this is where I would like to pass in different parameters like categories, search terms, etc
return {
resourceItemsReady: resourceItemsSub.ready(),
items: Meteor.collection('ResourceItems').find(),
navigation: params.navigation
};
}, MainScreen);
export default hoistNonReactStatic(container, MainScreen);
```
Seems maybe similar to this disucssion: https://github.com/inProgress-team/react-native-meteor/issues/84
Contributor guide
No contributing guide indexed for this repository
Assessment
This issue has not been assessed yet.