Reputation: 107
I'm learning reactNative and I cannot resolve an error. In the tutorial I'm following, we want to allow user to be able to add (or remove) movie to favourites and for that we are using Redux. After implementing the code when launch (through Expo Go on android), I've got the following error: undefined is not an object (evaluating 'store.getState'). Thanks Reducers:
// Store/Reducers/favoriteReducer.js
const initialState = { favoritesFilm: [] }
function toggleFavorite(state = initialState, action) {
let nextState
switch (action.type) {
case 'TOGGLE_FAVORITE':
const favoriteFilmIndex = state.favoritesFilm.findIndex(item => item.id === action.value.id)
if (favoriteFilmIndex !== -1){
nextState = {
...state,
favoritesFilm: state.favoritesFilm.filter( (item, index) => index !== favoriteFilmIndex )
}
}
else{
nextState = {
...state,
favoritesFilm: [...state.favoritesFilm, action.value]
}
}
return nextState || state
default:
return state
}
}
export default toggleFavorite
Store configure:
// Store/configureStore.js
import { createStore } from 'redux';
import toggleFavorite from './Reducers/favoriteReducer'
export default createStore(toggleFavorite)
App.js
import React from 'react';
import Navigation from './Navigation/Navigation';
import { Provider } from 'react-redux';
import { Store } from './Store/configureStore';
export default class App extends React.Component {
render(){
return (
<Provider store={Store}>
<Navigation/>
</Provider>
)
}
}
Film detail
import React from 'react'
import { StyleSheet, View, Text, ActivityIndicator, ScrollView, Image } from 'react-native'
import { getFilmDetailFromApi, getImageFromApi } from '../API/TMDBApi'
import moment from 'moment'
import numeral from 'numeral'
import { connect } from 'react-redux';
class FilmDetail extends React.Component {
constructor(props) {
super(props)
this.state = {
film: undefined,
isLoading: true
}
}
componentDidMount() {
getFilmDetailFromApi(this.props.navigation.state.params.idFilm).then(data => {
this.setState({
film: data,
isLoading: false
})
})
}
_displayLoading() {
if (this.state.isLoading) {
return (
<View style={styles.loading_container}>
<ActivityIndicator size='large' />
</View>
)
}
}
_displayFilm() {
const { film } = this.state
if (film != undefined) {
return (
<ScrollView style={styles.scrollview_container}>
<Image
style={styles.image}
source={{uri: getImageFromApi(film.backdrop_path)}}
/>
<Text style={styles.title_text}>{film.title}</Text>
<Text style={styles.description_text}>{film.overview}</Text>
<Text style={styles.default_text}>Sorti le {moment(new Date(film.release_date)).format('DD/MM/YYYY')}</Text>
<Text style={styles.default_text}>Note : {film.vote_average} / 10</Text>
<Text style={styles.default_text}>Nombre de votes : {film.vote_count}</Text>
<Text style={styles.default_text}>Budget : {numeral(film.budget).format('0,0[.]00 $')}</Text>
<Text style={styles.default_text}>Genre(s) : {film.genres.map(function(genre){
return genre.name;
}).join(" / ")}
</Text>
<Text style={styles.default_text}>Companie(s) : {film.production_companies.map(function(company){
return company.name;
}).join(" / ")}
</Text>
</ScrollView>
)
}
}
render() {
console.log(this.props)
return (
<View style={styles.main_container}>
{this._displayLoading()}
{this._displayFilm()}
</View>
)
}
}
const styles = StyleSheet.create({
main_container: {
flex: 1
},
loading_container: {
position: 'absolute',
left: 0,
right: 0,
top: 0,
bottom: 0,
alignItems: 'center',
justifyContent: 'center'
},
scrollview_container: {
flex: 1
},
image: {
height: 169,
margin: 5
},
title_text: {
fontWeight: 'bold',
fontSize: 35,
flex: 1,
flexWrap: 'wrap',
marginLeft: 5,
marginRight: 5,
marginTop: 10,
marginBottom: 10,
color: '#000000',
textAlign: 'center'
},
description_text: {
fontStyle: 'italic',
color: '#666666',
margin: 5,
marginBottom: 15
},
default_text: {
marginLeft: 5,
marginRight: 5,
marginTop: 5,
}
})
const mapStateToProps = (state) => {
return {
favoritesFilm: state.favoritesFilm
}
}
export default connect(mapStateToProps)(FilmDetail)
Package.json
{
"main": "node_modules/expo/AppEntry.js",
"scripts": {
"start": "expo start",
"android": "expo start --android",
"ios": "expo start --ios",
"web": "expo start --web",
"eject": "expo eject"
},
"dependencies": {
"@react-native-community/masked-view": "^0.1.10",
"@react-navigation/native": "^5.9.3",
"@react-navigation/stack": "^5.14.3",
"expo": "~40.0.0",
"expo-status-bar": "~1.0.3",
"moment": "^2.29.1",
"numeral": "^2.0.6",
"react": "16.13.1",
"react-dom": "16.13.1",
"react-native": "https://github.com/expo/react-native/archive/sdk-40.0.1.tar.gz",
"react-native-gesture-handler": "~1.8.0",
"react-native-reanimated": "~1.13.0",
"react-native-safe-area-context": "^3.1.9",
"react-native-screens": "~2.15.2",
"react-native-web": "~0.13.12",
"react-navigation": "^4.4.4",
"react-navigation-stack": "^2.10.4",
"react-redux": "^7.2.2",
"redux": "^4.0.5"
},
"devDependencies": {
"@babel/core": "~7.9.0",
"typescript": "~4.0.0",
"@types/react": "~16.9.35",
"@types/react-native": "~0.63.2"
},
"private": true
}
UPDATE: changing import { Store } from './Store/configureStore';
to import Store from './Store/configureStore';
in App.js makes it work
Already answer here: TypeError: undefined is not an object (evaluating 'store.getState')
Upvotes: 1
Views: 2793
Reputation: 1737
you have to change Store config:
export const store = createStore(toggleFavorite)
now you can import like this
import { store } from './Store/configureStore';
In mapStateToProps add (toggleFavorite) reducer where, that (favoritesFilm) state is present
const mapStateToProps = (state) => {
return {
favoritesFilm: state.toggleFavorite.favoritesFilm
}
}
Upvotes: 2