Adding redux to react native? - reactjs

i'm currently working on an app using react-native for the first time,
but i'm struggling to add redux.
i get this error TypeError: Cannot read property 'getState' of undefined and i don't know how to fix it.
this my code :
import React from "react";
import Home from "./home";
import { store } from "./redux/store";
import { Provider } from "react-redux";
/* #flow */
import { View, StyleSheet } from "react-native";
class App extends React.Component {
render() {
return (
<Provider store={store}>
<View style={styles.container}>
<Home />
</View>
</Provider>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1
}
});
store.js :
import { applyMiddleware, createStore } from "redux";
import logger from "redux-logger";
import reducer from "./reducer";
const middlewares = [logger];
const store = createStore(reducer, applyMiddleware(...middlewares));
export default store;
reducer.js :
import { combineReducers } from "redux";
import mapReducer from "../redux/maps/maps-reducer";
export default combineReducers({
map: mapReducer
});
maps-action.js:
import MAPSActionTypes from './maps-action-types';
export const currentlocation = () => ({
console.log(${location});
type : MAPSActionTypes.GET_CURRENT_LOCATION
});
maps-reducer.js:
import MAPSActionTypes from "./mapsactiontypes";
const INITIAL_STATE = {
location: {}
};
const mapReducer = (state = INITIAL_STATE, action) => {
switch (action.type) {
case MAPSActionTypes.GET_CURRENT_LOCATION:
return {
...state,
location: action.payload
};
default:
return state;
}
}
export default mapReducer;
home.js:
import React from 'react';
import {
StyleSheet,
View,
Text,
} from 'react-native';
import {connect} from 'react-redux'
const Home = (props) => {
return (
<View style={styles.container}>
<Text>welcome</Text>
<Text>{props.location}</Text>
</View>
);
};
const styles = StyleSheet.create({
container:{
flex:1,
justifyContent:'center',
alignItems:'center'
}
});
const mapStateToProps = (state) => {
return {
location: state.map.location
}
}
export default connect(mapStateToProps)(Home);
i'm all ears from more clarification or more details.
i will be very thankful if there's anyone who can help me to fix that problem.

The problem is you export default in store.js file.
export default store;
But in App you import it with {}. So the store you imported is undefined.
import { store } from "./redux/store";
The correct import is
import store from "./redux/store";

Related

ERROR Error: Could not find "store" in the context of "Connect(App)"

This is my error:
ERROR Error: Could not find "store" in the context of "Connect(App)". Either wrap the root component in a <Provider>, or pass a custom React context provider to <Provider> and the corresponding React context consumer to Connect(App) in connect options.
This error is located at:
in Connect(App)
in RCTView (created by View)
in View (created by AppContainer)
in RCTView (created by View)
in View (created by AppContainer)
in AppContainer
in ReactNativeApp(RootComponent)
ERROR TypeError: (0, _$$_REQUIRE(_dependencyMap[4], "./Redux/store").configureStore) is not a function. (In '(0, _$$_REQUIRE(_dependencyMap[4], "./Redux/store").configureStore)()', '(0, _$$_REQUIRE(_dependencyMap[4], "./Redux/store").configureStore)' is undefined)
ERROR Invariant Violation: Module AppRegistry is not a registered callable module (calling runApplication). A frequent cause of the error is that the application entry file path is incorrect.
This can also happen when the JS bundle is corrupt or there is an early initialization error when loading React Native.
This is my code
index.js
import { AppRegistry } from 'react-native';
import React from 'react';
import App from './Redux/App';
import { name as appName } from './app.json';
import { Provider } from 'react-redux';
import { configureStore } from './Redux/store';
const store = configureStore()
const RNRedux = () => (
<Provider store = { store }>
<App />
</Provider>
)
AppRegistry.registerComponent(appName, () => RNRedux);
redux/App.js
import React, { Component } from 'react';
import {
StyleSheet,
View,
Button,
Text
} from 'react-native';
import { connect, Provider } from 'react-redux';
import { bindActionCreators } from 'redux';
import * as countActions from './Action';
class App extends Component {
decrementCount() {
let { count, actions } = this.props;
count--;
actions.changeCount(count);
}
incrementCount() {
let { count, actions } = this.props;
count++;
actions.changeCount(count);
}
render() {
const { count } = this.props;
return (
<View styles={styles.container}>
<Button
title="increment"
onPress={() => this.incrementCount()}
/>
<Text style={styles.textCenter}>{count}</Text>
<Button
title="decrement"
onPress={() => this.decrementCount()}
/>
</View>
);
}
};
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center'
},
textCenter: {
textAlign: 'center'
}
});
const mapStateToProps = state => ({
count: state.count.count,
});
const ActionCreators = Object.assign(
{},
countActions,
);
const mapDispatchToProps = dispatch => ({
actions: bindActionCreators(ActionCreators, dispatch),
});
export default connect(mapStateToProps, mapDispatchToProps)(App)
Action.js
import { COUNTER_CHANGE } from './ActionType';
export function changeCount(count) {
return {
type: COUNTER_CHANGE,
payload: count
}
}
ActionType.js
export const COUNTER_CHANGE = 'COUNTER_CHANGE'
Reducer.js
import { COUNTER_CHANGE } from './ActionType';
const initialState = {
count: 0
};
const countReducer = (state = initialState, action) => {
switch(action.type) {
case COUNTER_CHANGE:
return {
...state,
count:action.payload
};
default:
return state;
}
}
export default countReducer;
store.js
import { createStore, combineReducers } from 'redux';
import countReducer from './Reducers'
const rootReducer = combineReducers(
{ count: countReducer }
);
const configureStore = () => {
return createStore(rootReducer);
}
export const store= createStore(configureStore);
How to solve this error and where is my error I don't know where I do a mistake
I'm doing a project like an example but it is it gives me an error
can you give me the suggestion on where I do a mistake and where something happen wrong
I'm adding redux dispatch and using useSelector in a class component with react native I'm trying to do many solutions but I don't understand properly how to do redux in-class component with react native
Issue
The code in your store.js file is a bit wonky.
There is no named configureStore export.
A store reference is exported, but it's an odd self-referencing amalgam of createStore and a custom store configurator function.
import { createStore, combineReducers } from 'redux';
import countReducer from './Reducers';
const rootReducer = combineReducers({
count: countReducer
});
const configureStore = () => {
return createStore(rootReducer); // <-- calls createStore again??
}
// This is the only export, but it oddly is passed the
// configureStore function instead of the Redux arguments
export const store = createStore(configureStore);
Solution
It's probably best to just create and export the store with the root reducer function.
import { createStore, combineReducers } from 'redux';
import countReducer from './Reducers';
const rootReducer = combineReducers({
count: countReducer
});
export const store = createStore(rootReducer);
Import store and pass to the Provider component.
import { AppRegistry } from 'react-native';
import React from 'react';
import App from './Redux/App';
import { name as appName } from './app.json';
import { Provider } from 'react-redux';
import { store } from './Redux/store'; // <-- import named export store
const RNRedux = () => (
<Provider store={store}>
<App />
</Provider>
);
I think I should understand your problem.
You make the same name of two components (APP), and you can change one component or screen.
Try this code in your store.js
import { createStore, combineReducers } from 'redux';
import countReducer from './Reducers'
const rootReducer = combineReducers(
{ count: countReducer }
);
export const store= createStore(rootReducer);

Error: Coming in react-navigation v3 with redux

Before Calling createReduxContainer please call createReactNavigationReduxMiddleware so that we know when to trigger your listener
I am trying to integrate react-navigation v3 with redux and this above problem is showing on my simulator
This is a tested sample of react-navigation(v3) and Redux. Here the react-navigation is integrated into Redux. However, I declined to use this method anymore. I believe integrating is not necessary when it is going to make things more complicated.
App.JS file :
import React, {Component} from 'react';
import { Provider } from "react-redux";
import { createStore, applyMiddleware, combineReducers } from "redux";
import { createStackNavigator } from "react-navigation";
import {
reduxifyNavigator,
createReactNavigationReduxMiddleware,
createNavigationReducer
} from "react-navigation-redux-helpers";
import MainScreen from "./Screens/MainScreen";
import SignUpScreen from "./Screens/SignUpScreen";
import rootReducer from "./src/rootReducer";
import ReduxNavigation from "./src/ReduxNavigation";
import { Directions } from 'react-native-gesture-handler';
const AppNavigator = createStackNavigator(
{
// LoginScreen: { screen: LoginScreen },
MainScreen: { screen: MainScreen },
SignUpScreen: { screen: SignUpScreen }
},
{
initialRouteName: "SignUpScreen"
}
);
const navReducer = createNavigationReducer(AppNavigator);
const appReducer = combineReducers({
nav: navReducer,
app: rootReducer
});
const middleware = createReactNavigationReduxMiddleware(
"root",
state => state.nav
);
export const AppNav = reduxifyNavigator(AppNavigator, "root");
const store = createStore(appReducer, applyMiddleware(middleware));
type Props = {};
export default class App extends Component<Props> {
render() {
return (
<Provider store={store}>
<ReduxNavigation />
</Provider>
);
}
}
ReduxNavigation.js :
import React from "react";
import { BackHandler } from "react-native";
import { connect } from "react-redux";
import { NavigationActions } from "react-navigation";
import { AppNav } from "../App";
class ReduxNavigation extends React.Component {
componentDidMount() {
BackHandler.addEventListener("hardwareBackPress", this.onBackPress);
}
componentWillUnmount() {
BackHandler.removeEventListener("hardwareBackPress", this.onBackPress);
}
onBackPress = () => {
const { nav, dispatch } = this.props;
if (nav.index === 0) {
return false;
}
dispatch(NavigationActions.back());
return true;
};
render() {
const { nav, dispatch } = this.props;
return <AppNav state={nav} dispatch={dispatch} />;
}
}
const mapStateToProps = state => ({
nav: state.nav
});
export default connect(mapStateToProps)(ReduxNavigation);
this code also support back button feature for Android devices.

React navigation Could not find "store" in the context of "Connect(AuthScreen)"

I'm trying to facebook login with my expo react native app. But i have a problem. I used redux. My app.js here.
import { createBottomTabNavigator, createAppContainer, createStackNavigator
} from 'react-navigation';
import AuthScreen from './screens/AuthScreen';
import { Provider } from 'react-redux'
import store from './store';
const MainNavigator = createBottomTabNavigator({
welcome: {screen: WelcomeScreen},
auth: { screen: AuthScreen },
main: {
screen: createBottomTabNavigator({
map: { screen: MapScreen },
deck: { screen: DeckScreen },
review: {
screen: createStackNavigator({
review: { screen: ReviewScreen },
settings: { screen: SettingsScreen }
})
}
})
}
})
class App extends React.Component {
render() {
return (
<Provider store={store} >
<View>
<MainNavigator/>
</View>
</Provider>
);
}
}
export default createAppContainer(MainNavigator)
And this is my AuthScreen.js
import React, { Component } from 'react';
import { View, Text } from 'react-native';
import { connect } from 'react-redux';
import * as actions from '../actions/auth_actions';
class AuthScreen extends Component {
componentDidMoun(){
this.props.facebookLogin();
}
render(){
return(
<View>
<Text>Auth</Text>
</View>
)
}
}
export default connect(null, actions)(AuthScreen);
I called facebookLogin() function inside my auth_action.js file
export const facebookLogin = () => async dispatch => {
let token = await AsyncStorage.getItem('fb_token');
if(token) {
dispatch({ type: FACEBOOK_LOGIN_SUCCESS, payload: token })
}else{
doFacebookLogin(dispatch);
}
}
reducer/index.js file
import { combineReducers } from 'redux';
export default combineReducers({
auth: () => { return {} }
});
And this is my store.js file.
import { createStore, compose, applyMiddleware } from 'redux';
import thunk from 'redux-thunk';
import reducers from '../reducers';
const store = createStore(
reducers,
{},
compose(
applyMiddleware(thunk)
)
);
export default store;
But i'm getting this error.
Invariant Violation: Could not find "store" in the context of "Connect(AuthScreen)". Either wrap the root component in a , or pass a custom React context provider to and the corresponding React context consumer to Connect(AuthScreen) in connect options.
What is a problem? Can you help me?
You have not connected your store to this component export default connect(null, actions)(AuthScreen); and you have passed null where you should pass some mapper and just action where you should define which functions you want to import from reducer.
import React, { Component } from "react";
import { connect } from "react-redux";
import * as actions from "../actions";
import {
createBottomTabNavigator,
createAppContainer,
createStackNavigator
} from "react-navigation";
import AuthScreen from "../screens/AuthScreen";
import HomeScreen from "../screens/HomeScreen";
import SettingsScreen from "../screens/SettingsScreen";
import DeckScreen from "../screens/DeckScreen";
import MapScreen from "../screens/MapScreen";
import ReviewScreen from "../screens/ReviewScreen";
const AppNavigator = createBottomTabNavigator({
home: { screen: HomeScreen },
auth: { screen: AuthScreen },
main: {
screen: createBottomTabNavigator({
map: { screen: MapScreen },
deck: { screen: DeckScreen },
review: {
screen: createStackNavigator({
review: { screen: ReviewScreen },
settings: { screen: SettingsScreen }
})
}
})
}
});
const AppContainer = createAppContainer(AppNavigator);
enter code here
class AppNavigation extends Component {
render() {
return <AppContainer screenProps={this.props} />;
}
}
export default connect(
null,
actions
)(AppNavigation);
import React, { Component } from "react";
import { Provider } from "react-redux";
import AppNavigation from "./navigation/AppNavigation";
import store from "./store";
class App extends Component {
render() {
return (
<Provider store={store}>
<AppNavigation />
</Provider>
);
}
}
export default App;

How correctly connect redux to react-native

I have react-native + redux application. In this application i have about 10 components (music, movies etc.)
But, i can't correctly connect redux to react-native. I have error "could not find store in either the context or props of..."
My App.js file
import App from './src/index';
export default App;
And my index.js file
import React, { Component } from 'react'
import { View } from 'react-native'
import { AppNavigator } from './nav/nav'
import { createStore, applyMiddleware } from 'redux';
import { Provider, connect } from 'react-redux';
import axios from 'axios';
import axiosMiddleware from 'redux-axios-middleware';
import reducer from './store/reducer';
import { listPosts } from './store/reducer';
const client = axios.create({
baseURL: 'https://xxxxxx.xxx',
responseType: 'json'
});
const store = createStore(reducer, applyMiddleware(axiosMiddleware(client)));
class App extends Component {
render() {
return (
<Provider store={store}>
<View style={{ flex: 1 }}>
<AppNavigator />
</View>
</Provider>
)
}
}
const mapStateToProps = state => {
let storedPosts = state.posts.map(repo => ({ key: repo.id, ...repo }));
return {
posts: storedPosts
};
};
const mapDispatchToProps = {
listPosts
};
export default connect(mapStateToProps, mapDispatchToProps)(App);

Redux, connect method not working. Data not fetched from store

I am learning redux. I have written an application for the same, first time. I am not able to understand why data isnt being fetched from store. Is there anything wrong with my connect call? Please help.
I am getting error that contactsList is undefined while calling map below, although connect should fetch that list as per my understanding.
ContactCards.js
import React, { Component } from 'react';
import Card from './Card';
import { connect } from 'react-redux';
const CardList = ({ contactsList }) => {
const cardsArray = contactsList.map(contact => (
<Card
key={contact.id}
name={contact.name}
email={contact.email}
phone={contact.phone}
website={contact.website}
city={contact.address.city}
companyName={contact.company.name}
id={contact.id} />
));
return (
<div className="jumbotron">
<div className='card-columns'>
{cardsArray}
</div>
</div>
);
};
const mapStateToProps = state => {
return { contactsList: state.contactsList };
};
const ContactCards = connect(mapStateToProps)(CardList);
export default ContactCards;
Reducer dataReducer
import ContactsList from '../components/MockContactsList';
import {loadContacts, updateContacts} from '../Actions/CardActions';
const INITIAL_STATE = {
contactsList: ContactsList
};
const dataReducer = (state = INITIAL_STATE, action) => {
switch(action.type) {
case loadContacts:
return state;
case updateContacts:
const updatedItems = state.contactsList.map(item => {
if(item.id === action.id){
return { ...item, ...action.payload }
}
return item
})
return updatedItems;
default:
return state;
}
};
export default dataReducer;
App.js
import React from 'react';
import ReactDOM from 'react-dom';
import App from './components/App';
import registerServiceWorker from './registerServiceWorker';
import '../node_modules/bootstrap/dist/css/bootstrap.min.css';
import reducers from './reducers/index';
import { createStore } from 'redux';
import { Provider } from 'react-redux';
const store = createStore(reducers, {});
ReactDOM.render(
<Provider store = {store}>
<App />
</Provider>
,document.getElementById('root'));
registerServiceWorker();
Reducers index.js
import { combineReducers } from 'redux';
import dataReducer from './dataReducer';
export default combineReducers({
dataReducer
});
index.js
import React from 'react';
import ReactDOM from 'react-dom';
import App from './components/App';
import registerServiceWorker from './registerServiceWorker';
import '../node_modules/bootstrap/dist/css/bootstrap.min.css';
import reducers from './reducers/index';
import { createStore } from 'redux';
import { Provider } from 'react-redux';
const store = createStore(reducers, {});
ReactDOM.render(
<Provider store = {store}>
<App />
</Provider>
,document.getElementById('root'));
registerServiceWorker();
You must first access your reducer state (dataReducer) then its property:
const mapStateToProps = state => {
return { contactsList: state.dataReducer.contactsList };
};
In your store you have a key of dataReducer:
export default combineReducers({
dataReducer
});
But you're accessing it as contactsList here:
const mapStateToProps = state => {
return { contactsList: state.contactsList };
};
So you probably need to have that key in your store instead:
export default combineReducers({
contactsList: dataReducer
});

Resources