Adam Wells
Adam Wells

Reputation: 47

Why can't I access my this.state.props session array from my mapStateToProps in React-Native Redux?

I am trying to store an array of Session objects. Each Session has an array of Hand objects. I am trying to set up a Redux store, but for some reason I can't access my store using mapStateToProps. None of the options in this.props.* have anything to do with my redux store.

My store is supposed to hold an array of session objects, and I want to display those objects in a simple FlatList, to get the concepts down before I create a customized FlatList. I show an example of exactly what I want using State, but I can't get it to work with Redux.

My {this.props.sessions} doesn't display anything, and I want it to display the name of the Session, the same way the State button does.

I have tried a lot of different configurations, including flipping through this.props.* trying to find something to output information.

I even tried to just use a simple "Count" variable with Redux, to just see if I could get that working, and that didn't work either.

Is there an underlying problem here?

My app runs just fine, but the button for "add new session with redux" just doesn't do anything when I press it.

//*HOME.JS
import React from 'react';
import { StyleSheet, View, Text, Button, FlatList} from 'react-native';
import { connect } from 'react-redux';
import { SessionObject } from './Session';

var session = new SessionObject("Session", []);
class Home extends React.Component {
  state = {
    SessionList : [],
    SessionCount : 1
  }
  render() {
    const { navigate } = this.props.navigation;   
      return (
        <View style={styles.container}>
          <View style={styles.container}>
            <Text>Home Screen!! :)</Text>
          </View>
          <View style={styles.style_flex3}>
          <Button title="Add new Session with State" onPress={() => this.addItem() } />
          <FlatList
            data={this.state.SessionList}
            renderItem={({item}) => this.SessionComponent(item)}
            keyExtractor={(item, index) => index.toString()}
            />
            <Text>{this.props.sessions}</Text>
            <Text>{this.props.Count}</Text>
            <Button title="Add new Session with Redux!" onPress={() => this.addNewSession() } />
            <FlatList
            data={this.props.sessions}
            renderItem={({item}) => this.SessionComponent(item)}
            keyExtractor={(item, index) => index.toString()}
            />
          </View>
        </View>
      );
    }
    addItem = () => { //USING STATE
      this.setState((state, props) => ({
        SessionList : [...state.SessionList, new SessionObject(state.SessionCount)],
        SessionCount : state.SessionCount + 1,
      }));
    };
    addNewSession = () => { //USING REDUX
      var newSession = new SessionObject("new-Session", []);
      this.props.addSession(newSession);
    };
}
const mapStateToProps = (state) => {
  return {
    sessions: state.reducer
  };
};
const mapDispatchToProps = (dispatch) => {
  return {
      addSession: (newSession) => {
        dispatch({
          type: "ADD_SESSION",
          payload: newSession
        });
      }
  };
};
export default connect(mapStateToProps, mapDispatchToProps)(Home);
//*STORE.JS
import React from 'react';
import { createStore } from 'redux';
import { SessionObject } from './screens/Session';

//var newSession1 = new SessionObject("Default", []);

const initialState = {
     currentSession: undefined,
     SessionList: [],
    //Count: 0,
}

export const reducer = (state = initialState, action) => {
    switch (action.type) {
        case "ADD_SESSION":
            state = {
                ...state,
                currentSession: action.payload,
                SessionList: [...state.SessionList, action.payload]
            };
            ...
    }
    return state;
};

const store = createStore(reducer);

export default store;
//THIS IS WHERE I WANT 
TO ACCESS THIS.PROPS.SESSIONS
            <Text>{this.props.sessions}</Text>
            <Text>{this.props.Count}</Text>
            <Button title="Add new Session with Redux!" onPress={() => 
               this.addNewSession() } />
            <FlatList
            data={this.props.sessions}
            renderItem={({item}) => this.SessionComponent(item)}
            keyExtractor={(item, index) => index.toString()}
            />

I want to display the list of Sessions in my redux store in the Flatlist, and I want the "add" button to create more Sessions when I tap it.

(basically recreate what this.State is already doing, but with redux).

EDIT: This is my App.js file, where I use the Provider. Is this an incorrect way of using provider?

import React from 'react';
import { createStackNavigator, createAppContainer } from 'react-navigation';
import { Provider } from 'react-redux';
import store from './store';
import Home from './screens/Home';
import Session from './screens/Session';
import Hand from './screens/Hand';

export default class App extends React.Component {
  render() {
      return (
        <Provider store={store}>
          <AppContainer />
        </Provider>
      );
    }
}
//creating the stack navigation variable
const AppStackNavigator = createStackNavigator({
  Home: Home,
  Session: Session,
  Hand: Hand,
})

//Contains the app navigation variable,
//using a navigator variable
const AppContainer = createAppContainer(AppStackNavigator);

Upvotes: 1

Views: 451

Answers (1)

Vinicius
Vinicius

Reputation: 1365

You need to attach the Provider to make redux store available to your connected components. You can find proper instructions here: https://react-redux.js.org/api/provider . Let me know if you have further questions.

EDIT:

Your provider is correctly attached.

I believe I found your problem. Your application state managed by redux is the one returned by the reducer. So, if you want to get the SessionList from the state, you should use

const mapStateToProps = (state) => {
  return {
    sessions: state.SessionList
  };
}; 

Upvotes: 1

Related Questions