Reputation: 3727
I just started to use redux on my react site. Pretty small. (and I'm following this tutorial https://medium.com/front-end-developers/handcrafting-an-isomorphic-redux-application-with-love-40ada4468af4#.mhkgga84t plugging in some codes to my react site just in case). But when I was in progress and trying to acceess this.props.store
it's not available even when I have <Provider store={store}>
in my app. Here's my client and app code (I can provide more I just don't know what else to add):
// src/client.js
import React from 'react';
import ReactDOM from 'react-dom';
import { Router } from 'react-router';
import { routes } from './routes';
import { browserHistory } from 'react-router'
import { createStore, combineReducers } from 'redux';
import { Provider } from 'react-redux';
import * as reducers from './reducers';
import { fromJS } from 'immutable';
let initialState = window.__INITIAL_STATE__;
Object.keys(initialState).forEach(key => {
initialState[key] = fromJS(initialState[key]);
});
const reducer = combineReducers(reducers);
const store = createStore(reducer, initialState);
console.log('store', store);
ReactDOM.render(<Provider store={store}><Router routes={routes} history={browserHistory} store={store} /></Provider>, document.getElementById('app'));
but I can't access store
from this.props
. It should be available here right? So I can do const { todos, dispatch } = this.props;
eventually?
// src/components/app.js
import React from 'react';
import { Link } from 'react-router';
import HeaderComponent from './common/header';
import ShareFooterComponent from './common/share-footer';
import FooterComponent from './common/footer';
import { bindActionCreators } from 'redux';
import * as ListingActions from '../actions/listing';
import { connect } from 'react-redux';
export default class AppComponent extends React.Component {
render() {
console.log('apps', this.props);
return (
<div>
<HeaderComponent />
{ this.props.children }
<ShareFooterComponent />
<FooterComponent />
</div>
);
}
}
Am I missing anything?
Upvotes: 3
Views: 2248
Reputation: 342
So first thing I noticed that does not seem right is you are passing the store to both the provider and the router
<Provider store={store}><Router routes={routes} history={browserHistory} store={store} /></Provider>
Where it would only be needed in Provider like
<Provider store={store}><Router routes={routes} history={browserHistory} /></Provider>
Then like Ashley Coolman said you will need to connect the component to redux.
It can be done with the decorator if your build is set up for it. However you can also import the connect
function from react-redux. Documentation on it can be found here.
The way I would hook up your component is the following
class AppComponent extends React.Component {
render() {
console.log('apps', this.props);
return (
<div>
<HeaderComponent />
{ this.props.children }
<ShareFooterComponent />
<FooterComponent />
</div>
);
}
}
function addTodo(todo) {
return { type: ADD_TODO, payload: todo }
}
function mapStateToProps(state) {
// the state is from store.getState()
// example will pass a todos prop to the connected component
// so if you want all the state in this component use the spread operator
return {
todos: state.todos
}
}
function mapDispatchToProps(dispatch) {
// bindActionCreators will wrap all the function in the passed in object
// with the dispatch function so that the actionCreators can be called
// directly; without dispatch eg this.props.addTodo(sometodo)
return bindActionCreators({ addTodo }, dispatch)
}
export default connect(mapStateToProps, mapDispatchToProps)(AppComponent )
After that you will have as props on your component both addTodo
(function) and todos
. Giving you
this.props.todos
this.props.addTodo()
Upvotes: 2
Reputation: 11585
You don't seem to be wiring up your state with the connect
decorator. If I am reading the tutorial correctly you should include the line (or something similar based on your state structure):
@connect(state => ({ todos: state.todos }))
or without decorator syntax (more succint version in the comments):
AppComponent = connect(state => ({ todos: state.todos }), null)(AppComponent);
export default AppComponent;`
Upvotes: 3