Allan.C
Allan.C

Reputation: 41

React Router Link onClick redux action call not calling reducer

Using react router's Link tag to pass an action on 'onClick' before updating the new state data and rendering in new component on display. Reducer isn't called or any changes made to state. No idea why. Any help would be greatly appreciated.

Reducer that doesn't log 'reducer working'. On home screen logs 'reducer called'

import GATHER_NEIGHBOURS from '../actions';
import GATHER_REGION from '../actions';
import GATHER_ALL from '../actions';

import _ from 'lodash';


const displayData = (state = {}, action) => {
    console.log("reducer called!");
    switch (action.type) {
        case 'GATHER_NEIGHBOURS':
            console.log("reducer working!");
            return { display: 'neighbours' };
        case 'GATHER_REGION':
            return {};
        case 'GATHER_ALL':
            return {};
  }
  return state;
};

export default displayData;

Action that logs 'working'

export const GATHER_NEIGHBOURS = "GATHER_NEIGHBOURS";

export function importNeighbourData (data) {
    console.log('action working');
    return {
        type: GATHER_NEIGHBOURS,
        payload: data
    };
}

Container with onClick that fires

import React, { Component } from 'react';
import { Link } from 'react-router-dom';
import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';
import { importNeighbourData, importRegionData, importAllData } from '../actions';


class HomeMenu extends Component {
    constructor(props){
        super(props);
        this.handleClick50 =this.handleClick50.bind(this);
        this.handleClick200 =this.handleClick200.bind(this);
        this.handleClickAll =this.handleClickAll.bind(this);
    }

    handleClick50(e) {
        console.log('click called');
        importNeighbourData(this.props.planets);
    }

    handleClick200(e) {
        importRegionData(this.props.planets);
    }

    handleClickAll(e) {
        importAllData(this.props.planets);
    }

    render(){
        return (
            <div className="homeMenu">
                <div>
                    <Link to="/browse" onClick={this.handleClick50}>
                        <img alt="earth-and-moon-icon" src="imgs/earth-and-moon.png"></img> 
                        Neighbourhood<br/>
                        (less than 50 parsecs)
                    </Link>
                </div>
                <div>
                    <Link to="/browse" onClick={this.handleClick200}>
                        <img alt="solar-system-icon" src="imgs/solar-system.png"></img> 
                        Regional<br/>
                        (less than 200 parsecs)
                    </Link>
                </div>
                <div>
                    <Link to="/browse" onClick={this.props.handleClickAll}>
                        <img alt="galaxy-icon" src="imgs/galaxy-view.png"></img> 
                        All
                    </Link>
                </div>
            </div>
        );
    }
}

function mapStateToProps({ planets }, ownProps) {
    return { planets };
}

function mapDispatchToProps(dispatch, ownProps) {
    return bindActionCreators({importNeighbourData, importRegionData, importAllData}, dispatch);
}

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

Upvotes: 1

Views: 1842

Answers (1)

Raghav Garg
Raghav Garg

Reputation: 3707

In your code, you are calling

importNeighbourData();
importRegionData();
importAllData();

actually which should be called like,

this.props.importNeighbourData();
this.props.importRegionData();
this.props.importAllData();

Because, the redux will listen only to the dispatch bound actions, so to enable that, we use connect function from react-redux package, so that redux will know to update itself upon the action execution.

connect will bind your action to the component props on this.props, so it is very essential to use this.props.action() and not just action()

The only use case for bindActionCreators is when you want to pass some action creators down to a component that isn't aware of Redux, and you don't want to pass dispatch or the Redux store to it.

Upvotes: 1

Related Questions