Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

React Redux Mapping state to props not working

So I'm trying to learn React with Redux and so far I think I've been able to work out most of the code needed to make it work but I'm having an issue with getting my state passed down to my component. I am using Visual Studio 2017's ASP.NET Core project template that has react and redux boilerplate codes and they used this:

export default connect(
  state => state.weatherForecasts,
  dispatch => bindActionCreators(actionCreators, dispatch)
)(FetchData);

I tried doing the same thing with my own component like so:

export default connect(
  state => state.lecture,
  dispatch => bindActionCreators(actionCreators, dispatch)
)(LectureTable);

but when trying to access the contents of my props, the properties I want to get are tagged as undefined. I checked through Redux devtools that my initial state exists but my component is unable to see the props I'm trying to pass to it. The weird thing is I just imitated the boilerplate code but it isn't working yet the boilerplate code works just fine (ie I can go to the component and log out its initial state).

Since I'm following the format used by Visual Studio,my actioncreators, reducers, and constants are in one file shown below:

const GET_LECTURES = "GET_LECTURES";

const initialState = {
    lectures: [],
    selectedLecture: {},
    isLoading: false,
    test: 0
};

export const actionCreators = {
    requestLectures: isLoading => async (dispatch) => 
    {    
      if (!isLoading) {
        // Don't issue a duplicate request (we already have or are loading the requested data)
        return;
      }

      dispatch({ type: GET_LECTURES });

      const url = `api/lecture/`;
      const response = await fetch(url);
      const lectures = await response.json();

      dispatch({ type: RECEIVE_LECTURES, payload: lectures });
    } 
  };

export const reducer = (state = initialState, action) => {
    switch (action.type) {
    case GET_LECTURES:
        return { ...state, isLoading: true }; 
        default:
        return state;
    }
};

I'm sorry if its all messy. I'm really just starting to begin to understand redux..

Edit My component code:

import React, { Component } from 'react';
import {Button, Table, Label, Menu, Icon} from 'semantic-ui-react';
import { bindActionCreators } from 'redux';
import { connect } from 'react-redux';
import {actionCreators} from './../../store/Lecture';

export class LectureTable extends Component {

  componentWillMount(){
   // this.props.requestLectures(this.props.isLoading);
    console.log(this.props.test);
  }

  render() {
    return (
        <Table size='large'>
        {/*removed to make it cleaner..currently only has static data too lol*/}
      </Table>
    )
  }
}



export default connect(
  state => state.lecture,
  dispatch => bindActionCreators(actionCreators, dispatch)
)(LectureTable);

where my store is configured:

import { applyMiddleware, combineReducers, compose, createStore } from 'redux';
import thunk from 'redux-thunk';
import { routerReducer, routerMiddleware } from 'react-router-redux';
import * as Lecture from './Lecture';
import * as Counter from './Counter';
import * as WeatherForecasts from './WeatherForecasts';

export default function configureStore(history, initialState) {
  const reducers = {
    lecture: Lecture.reducer,
    counter: Counter.reducer,
    weatherForecasts: WeatherForecasts.reducer
  };

  const middleware = [
    thunk,
    routerMiddleware(history)
  ];

  // In development, use the browser's Redux dev tools extension if installed
  const enhancers = [];
  const isDevelopment = process.env.NODE_ENV === 'development';
  if (isDevelopment && typeof window !== 'undefined' && window.devToolsExtension) {
    enhancers.push(window.devToolsExtension());
  }

  const rootReducer = combineReducers({
    ...reducers,
    routing: routerReducer
  });

  return createStore(
    rootReducer,
    initialState,
    compose(applyMiddleware(...middleware), ...enhancers)
  );
}

my index.js

import React from 'react';
import ReactDOM from 'react-dom';
import { Provider } from 'react-redux';
import { ConnectedRouter } from 'react-router-redux';
import { createBrowserHistory } from 'history';
import configureStore from './store/configureStore';
import App from './pages/App';
import registerServiceWorker from './registerServiceWorker';

// Create browser history to use in the Redux store
const baseUrl = document.getElementsByTagName('base')[0].getAttribute('href');
const history = createBrowserHistory({ basename: baseUrl });

// Get the application-wide store instance, prepopulating with state from the server where available.
const initialState = window.initialReduxState;
const store = configureStore(history, initialState);

const rootElement = document.getElementById('root');

ReactDOM.render(
  <Provider store={store}>
    <ConnectedRouter history={history}>
      <App />
    </ConnectedRouter>
  </Provider>,
  rootElement);

registerServiceWorker();
like image 457
kobowo Avatar asked Jun 05 '26 16:06

kobowo


2 Answers

The first argument to connect() should be a function that returns an object - with the props you want added as keys, and their value being the value from state. e.g.

state => ({ lecture: state.lecture })
like image 101
SamVK Avatar answered Jun 08 '26 00:06

SamVK


I found the solution. First of all I'm a noob both to stackoverflow and to react so I apoligize for all my inconsistencies (if thats the right term?).

What I found out:

  1. I am using react router
  2. I was doing the connect method to a subcomponent of the component being rendered by the router
  3. I placed the connect method to the parent component and it worked

Some notes:

  • state => state.lecture still works
  • I will take all of your advices to heart and change my code accordingly
  • The only reason I was adamant with solving the problem using the code I had was because I couldn't accept the fact that boilerplate code wouldn't work unless I had done something specifically different from what the boilerplate did. I just didn't take into account that the router played a huge role with it.
  • I repeat...I'm a react noob so I'm sorry for wasting your time T_T

Edit again: I was able to connect a different child component with the Redux store. I'm trying to look at why I still can't do it for that specific component that caused me to ask this question. I'll update my answer once I find the reason.

like image 25
kobowo Avatar answered Jun 07 '26 23:06

kobowo



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!