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();
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 })
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:
Some notes:
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With