I am working on a react native app and I have everything hooked up to a redux store so that I can manage data in that way.
I am curious about the possibility of dispatching data from the App.js
component which at the moment I use to essentially route my app. The use case would be to make an API call in App.js
and set data in redux store from there so that the app presumably makes that call every time it is opened. I know componentDidMount for instance runs the code once when the app is opened but then never again unless its closed and reopened. I assume that App.js
might be better for something like this. If that assumption is incorrect my apologies as I am still learning.
In the example below, how would I run callApi
and setData
from App.js
to the Redux Store if that is possible? Or should I avoid this an try to set a global variable?
Below is sample code:
App.js
import React, {Component} from 'react';
import {createBottomTabNavigator} from 'react-navigation-tabs'
import { createAppContainer, createSwitchNavigator } from 'react-navigation';
import { Ionicons } from '@expo/vector-icons';
import { Provider } from 'react-redux';
import { createStore } from 'redux';
import ourReducer from './store/reducer';
const store = createStore(ourReducer);
global.x = 'https://volleybuddy.metis-data.site'
import Home from './components/Home'
import Profile from './components/Profile'
import Login from './components/Login'
import SignUp from './components/SignUp'
import StartScreen from './components/StartScreen'
export default class App extends Component {
render(){
return (
<Provider store={ store }>
<AppContainer/>
</Provider>
);
}
}
const bottomTabNavigator = createBottomTabNavigator(
{
Home: {
screen: Home,
navigationOptions: {
tabBarIcon: ({ tintColor }) => (
<Ionicons name="ios-home" size={25} color={tintColor}/>
// <Icon name="qrcode" size={25} color={tintColor} />
)
}
},
Profile: {
screen: Profile,
navigationOptions: {
tabBarIcon: ({ tintColor }) => (
// <Icon name="search" size={25} color={tintColor} />
<Ionicons name="md-person" size={25} color={tintColor}/>
)
}
},
},
{
initialRouteName: 'Home',
tabBarOptions: {
activeTintColor: '#eb6e3d'
}
}
);
const RootSwitch = createSwitchNavigator({
StartScreen,
SignUp,
Login,
bottomTabNavigator
});
const AppContainer = createAppContainer(RootSwitch);
Reducer.js (I set up my reducer something like this)
import { combineReducers } from 'redux';
const INITIAL_STATE = {
data: null
};
const ourReducer = (state = INITIAL_STATE, action) => {
const newState = { ...state };
switch (action.type) {
case "SET_DATA":
return{
...state,
data: action.value
}
break;
}
return newState;
};
export default combineReducers({
reducer: ourReducer,
});
Home.js (Lets just say if I want to move callApi to run also in App.js)
import React, {Component} from 'react';
import { connect } from 'react-redux';
class Home extends Component {
//NOT REAL CODE, JUST CONCEPT
callApi =() => {
fetch(....)
let data = response
this.props.setData(data)
}
render() {
return (
<React.Fragment>
<View>
<Button onPress={this.callApi}>
<Text>toggle tracking</Text>
</Button>
</View>
</React.Fragment>
);
}
}
const mapStateToProps = (state) => {
const { reducer } = state
return { reducer }
};
const mapDispachToProps = dispatch => {
return {
setData: (x) => dispatch({ type: "SET_DATA", value: x}),
};
};
export default connect(mapStateToProps,
mapDispachToProps
)(Home)
You can dispatch data from anywhere in the app as long as you can get a reference to the store using
store.dispatch
, in this case you can dispatch and action App component after the store is instantiated, but the App component itself is not connected to the store so it unable to re-render in response to changes on it, but this should not be a problem for you in this case.