react-redux-universal-hot-example
react-redux-universal-hot-example copied to clipboard
An action is not dispatching
Hi all !!! I've created a new redux module called portfolio.js, here is the content of the module:
const INCREMENTPORTFOLIO = 'redux-example/portfolio/INCREMENTPORTFOLIO';
const LOAD = 'redux-example/portfolio/LOAD';
const LOAD_SUCCESS = 'redux-example/portfolio/LOAD_SUCCESS';
const LOAD_FAIL = 'redux-example/portfolio/LOAD_FAIL';
const INCLIKE = 'redux-example/portfolio/INCLIKE';
const initialState = {
counter: 74,
loaded: false,
list: []
};
export default function portfolio(state = initialState, action = {}) {
switch (action.type) {
case LOAD:
return {
...state,
loading: true
};
case LOAD_SUCCESS:
return {
...state,
loading: false,
loaded: true,
list: action.result
};
case LOAD_FAIL:
return {
...state,
loading: false,
loaded: false,
error: action.error
};
case INCLIKE:
return state;
case INCREMENTPORTFOLIO:
const {counter} = state;
return {
...state,
counter: counter + 1
};
default:
return state;
}
}
export function incrementportfolio() {
return {
type: INCREMENTPORTFOLIO
};
}
export function isLoaded(globalState) {
return globalState.portfolio && globalState.portfolio.loaded;
}
export function load() {
return {
types: [LOAD, LOAD_SUCCESS, LOAD_FAIL],
promise: (client) => client.get('/loadPortfolio')
};
}
export function inclike(index) {
return {
type: INCLIKE,
payload: {
index: index
}
};
}
then I have included it properly in reducer.js inside redux/modules and then I have created a component called PorfolioList.js with this code:
import React, {Component, PropTypes} from 'react';
import {bindActionCreators} from 'redux';
import {connect} from 'react-redux';
import {incrementportfolio} from 'redux/modules/portfolio';
@connect(
state => ({counter: state.portfolio.counter}),
dispatch => bindActionCreators({incrementportfolio}, dispatch))
export default class PortfolioList extends Component {
static propTypes = {
counter: PropTypes.number,
incrementportfolio: PropTypes.func.isRequired
}
render() {
const {counter} = this.props;
return (
<button className="btn btn-default" onClick={incrementportfolio}>
You have clicked me {counter} time{counter === 1 ? '' : 's'}.
</button>
);
}
}
I have included this component properly in components/index.js and here comes the issue, the component is rendered well in the page and the button shows the initial value but the onclick doesn't fires the action. In redux dev tools I dispatch manually the action and the state is modified correctly. Why the onclick of the button is not firing the action ? Can you help me please ??
In button onClick event is not properly bind to function. this line: button className="btn btn-default" onClick={incrementportfolio}> change to: button className="btn btn-default" onClick={this.props.incrementportfolio}>
OR
this line: const {counter} = this.props; change to: const {counter, incrementportfolio} = this.props;
Hi ananddodia, thanks very much for your help. I initially typed this:
const {counter, incrementportfolio} = this.props;
but it gives me this error:
16:21 error "incrementportfolio" is already declared in the upper scope no-shadow
it is weird, does it ? because of that I decided to write this line in that way but I'll test your other option.
Thanks a lot, I'll give you the result of the test.
It works like a charm !!
... button className="btn btn-default" onClick={this.props.incrementportfolio}>
it works !! but the question is why I get this error ?
16:21 error "incrementportfolio" is already declared in the upper scope no-shadow
Why I can't to get incrementportfolio in this way ?
const {counter, incrementportfolio} = this.props;
Can you answer this question ?
Thanks in advance
Because you have
import {incrementportfolio} from 'redux/modules/portfolio';
in your code already.
So by doing const {counter, incrementportfolio} = this.props;
you are redefining with same name.
@ycruzb sorry for late reply I am stuck in other work(Using this repo. I am trying to implement code split based on modules so only necessary js css are loaded and not one single js css.) helping hands are appreciated. But whatever @parth-choudhary said is absolutely right. Thank you @parth-choudhary. @ycruzb you can if you still dont wan to change this line: const {counter, incrementportfolio} = this.props; than you can call portfolio all export function in one single object and then access by .(dot) operator.
change to this: import * as portfolio from 'redux/modules/portfolio'; So now you can access any function like wise portfolio.functionName (ex. portfolio.incrementportfolio and portfolio.isLoaded and so on.) Hope you are getting what I mention. if not, can get back to me. :-)