delinear
delinear

Reputation: 2805

Dispatch is not available in this.props

I'm very new to React and trying to write an application which outputs a portfolio to one part of the page and, based on user interaction with that portfolio, displays some information in a lightbox/modal elsewhere in the DOM.

This requires that my two rendered components have some kind of shared state, and my understanding is that the best (or one of the best) way to achieve this is with Redux. However, being new to React and now adding Redux into the mix, I'm a little out of my depth.

I've created some (for now very dumb) action creators and reducers, all I'm trying to do initially is fetch some JSON and add it to my store. However, I'm not able to access dispatch from within my component and I'm not really sure where I'm going wrong.

If I console.log this.props from within my component I get an empty object, "{}".

Here are the main parts, any pointers would be really appreciated:

App.js:

import React from 'react';
import ReactDOM from 'react-dom';
import { Provider } from 'react-redux';
import { createStore } from 'redux';
import store from './redux/store';
import { Portfolio } from './redux/components/portfolio';

ReactDOM.render(
  <Provider store={store}>
    <Portfolio />
  </Provider>,
  document.getElementById('portfolioCollection')
);

actions/actionCreators.js:

export const populatePortfolio = obj => ({
  type: POPULATE_PORTFOLIO, 
  obj
});

export const populateLightbox = obj => ({
  type: POPULATE_LIGHTBOX, 
  obj
});

portfolio.js:

import React from 'react';
import { bindActionCreators } from 'redux';
import { connect } from 'react-redux';
import * as actionCreators from '../actions/actionCreators';

export class Portfolio extends React.Component {

    componentDidMount() {
        this.getPortfolioData();
    }

    getPortfolioData() {
        fetch('/data.json')
        .then( (response) => {
            return response.json()
        })
        .then( (json) => {
            // dispatch action to update portfolio here
        });
    }

  render() {
    return(
      // render component
    );
  }
}

function mapStateToProps(state){
  console.log('state', state);
  return {
    state: state
  }
};

function mapDispatchToProps(dispatch) {
  console.log('dispatch', dispatch);
  return {
    actions: bindActionCreators({ populatePortfolio: populatePortfolio }, dispatch)
  };
}

export default connect(
    mapStateToProps,
    mapDispatchToProps
)(Portfolio);

Upvotes: 1

Views: 855

Answers (2)

H&#229;ken Lid
H&#229;ken Lid

Reputation: 23084

this.props is empty because you have not passed any props. You are using the unconnected component instead of the one that has been connected to redux.

To fix this, replace this line:

import { Portfolio } from './redux/components/portfolio';

with

import Portfolio from './redux/components/portfolio';

You are exporting both the connected and the unconnected component. You probably only want the last export. Since the connected component is exported as default you import it without using {} deconstruction.

unless you need to import the unconnected component in tests or something like that, you can remove the export statement from this line, since it makes no sense to export something that you don't intend to import in another file.

export class Portfolio extends React.Component {

Upvotes: 4

Andy Ray
Andy Ray

Reputation: 32076

You aren't meant to manually call dispatch in your components. The action creator function is automatically bound to dispatch for you. Simply call this.props.populatePortfolio() in your component.

Upvotes: 1

Related Questions