I not 100% sure if I am doing this right as per the redux design.
import React from 'react';
import {connect} from 'react-redux';
import {bindActionCreators} from 'redux';
import 'materialize-css/sass/materialize.scss';
import NavigationContainer from './NavigationContainer';
import AddStorageModal from './AddStorageModal.js'
import {loadAddStorageModal, createNewStorage} from '../actions/StorageActions.js'
import '../styles/main.scss';
class App extends React.Component {
render() {
return (
<div>
<NavigationContainer />
<AddStorageModal {...this.props} />
</div>
)
}
}
function mapStateToProps(state) {
return {
storages: state.storages
};
}
function matchDispatchToProps(dispatch){
return bindActionCreators({loadAddStorageModal: loadAddStorageModal, createNewStorage: createNewStorage}, dispatch);
}
export default connect(mapStateToProps, matchDispatchToProps)(App);
StorageActions
export function fetchStorage() {
return function(dispatch) {
var payload = [
{
id: 1,
name: "Fridge2"
},
{
id: 2,
name: "Closet2"
},
{
id: 3,
name: "Car2"
}
];
dispatch({type: "Fetch_Storage", payload: payload});
}
}
export function loadAddStorageModal(load) {
return function(dispatch) {
dispatch({type: "Load_Add_Storage_Modal", payload: load});
}
}
export function createNewStorage(storage) {
return function(dispatch) {
dispatch({type: "New_Storage_Created", payload: storage});
}
}
Reducer
export default function reducer(state = {
fetchedStorages: [],
openAddStorageModal: false
}, action) {
switch (action.type) {
case "Fetch_Storage": {
return {
fetchedStorages: action.payload
}
}
case "Load_Add_Storage_Modal": {
return {
openAddStorageModal: action.payload,
fetchedStorages: state.fetchedStorages
}
}
case "New_Storage_Created": {
return {
openAddStorageModal: false,
}
}
}
return state;
}
AddStorageModal
import React from 'react';
import 'materialize-css/sass/materialize.scss';
import 'materialize-css/js/materialize.js';
import 'font-awesome/scss/font-awesome.scss';
import '../styles/main.scss';
export default class AddStorageModal extends React.Component {
constructor() {
super();
this.state = {storageName: ""}
}
handleChange(event) {
this.setState({storageName: event.target.value});
}
render() {
if (this.props.storages.openAddStorageModal) {
$('#add-new-storage-modal').openModal({ dismissible: false });
}
return (
<div id="add-new-storage-modal" className="modal" >
<div className="modal-content">
<h6>Enter your new Storage (Freezer, Pantry, etc.) </h6>
<div className="row">
<form>
<div className="input-field col s12 m12 l12 ">
<input id="storage_name" type="text" className="validate" value={this.state.storageName} onChange={this.handleChange} />
<label htmlFor="storage_name">Storage Name</label>
</div>
<br />
<h4 className="center">OR</h4>
<h6>Enter in the sharing key you were given.</h6>
<div className="input-field col s12 m12 l12 ">
<input id="sharing_key" type="text" className="validate" />
<label htmlFor="sharing_key">Sharking Key</label>
</div>
</form>
</div>
</div>
<div className="modal-footer">
Add
<a href="#!" className="modal-action modal-close waves-effect waves-green btn-flat" onClick={() => this.props.loadAddStorageModal(false) }>Cancel</a>
</div>
</div>
)
}
}
I get
Uncaught TypeError: Cannot read property 'setState' of undefined
So I am not sure if this just means I am doing redux wrong or if I just made some general error.
You can't pass a generic function reference, you need to keep the reference to this. You have 2 options:
bind this to the function, like #nuway said in his answer.
Use an arrow function, which also keeps the this reference: onChange={ (event) => this.handleChange(event) }
you need to bind to this for the handleChange handler, otherwise this inside handleChange funtion won't be the react component but rather the input element itself.
onChange={this.handleChange.bind(this)}
Related
First Compoent
import React from "react";
import ReactDOM from "react-dom";
import PropTypes from 'prop-types'
import { withRouter } from "react-router-dom";
import { gateway as MoltinGateway } from "#moltin/sdk";
import {getList,updateList} from "./../Action/Action";
import { connect } from "react-redux";
import Icon from '#material-ui/core/Icon';
import Payment from "./../Payment/Payment";
import Tick from './done.png'
export class Item extends React.Component {
constructor(props) {
super(props);
this.state = {};
this.pickItem = this.pickItem.bind(this);
}
UpdateList ={}
pickItem(pickedItem, id) {
//console.log(pickedItem,id)
document.getElementById(id).classList.toggle("active")
this.UpdateList = pickedItem.map(function(data,i){
if(data.id == id && i<=5 && data.pickedItem!=='Yes'){
data.pickedItem = 'Yes'
return data
}else{
data.pickedItem = 'No'
return data
}
});
}
componentWillMount() {
this.props.getList();
}
updateList(){
//console.log(this.UpdateList)
this.props.updateList(this.UpdateList)
this.props.history.push({
pathname: '/Payment',
});
}
render() {
//const { pickedItem } = this.state;
const {list} = this.props
let filtereDate;
if(list!==undefined && list.length>0){
filtereDate = list.map(function(data,i){
if(i<=5){
return(
<div key={data.id} ref={data.id} id={data.id} onClick={this.pickItem.bind(this, list, data.id )} className='item-list'>
<span className="tickMark"><img src={Tick} /></span>
<div className="logoWarapper">
<img
src="https://rukminim1.flixcart.com/image/660/792/jmdrr0w0/shirt/q/q/r/xxl-tblwtshirtful-sh4-tripr-original-imaf9ajwb3mfbhmh.jpeg?q=50"
width="100"
height="100"
alt=""
/>
</div>
<div className="itemWarapper">
<h3>{data.name}</h3>
<p>
<span>₹</span>
<span>{data.id}</span>
</p>
</div>
</div>
)
}
}.bind(this));
}
return (
<div className="ItemPage">
<header>
<h1>Online shopping</h1>
<h2>Visit | Pick | Pay</h2>
</header>
{filtereDate}
<div className="btnWrp">
<button onClick={this.updateList.bind(this)} className="button">Make Payment</button>
</div>
</div>
);
}
}
Item.propTypes = {
list: PropTypes.object,
getList: PropTypes.func,
updateList:PropTypes.func
}
function mapStateToProps(state){
const Items= state
return {
list : Items.list
}
}
const mapDispatchToProps = dispatch => ({
getList: () => dispatch(getList()),
updateList: (list) =>
dispatch(updateList(list))
})
export default withRouter(connect(
mapStateToProps,
mapDispatchToProps
)(Item));
Sages file
import { put, takeLatest, all, call,select } from "redux-saga/effects";
function* fetchNews() {
const json = yield fetch(
"http://petstore.swagger.io/v2/pet/findByStatus?status=available"
).then(response => response.json());
yield put({ type: "GET_LIST_SUCCESS", json: json });
}
function * updateNewList(data){
///console.log(data.payload)
yield put({ type: "GET_LIST_SUCCESS", list: data.payload });
}
function * fetchupateList(){
const signals = yield select(store => store)
console.log(signals)
}
function* actionWatcher() {
yield takeLatest("GET_LIST_REQUEST", fetchNews);
yield takeLatest("GET_UPDATED_LIST_REQUEST", fetchupateList);
yield takeLatest("UPDATE_LIST_REQUEST", updateNewList);
}
export default function* rootSaga() {
yield all([actionWatcher()]);
}
**Second Component **
import React from "react";
import ReactDOM from "react-dom";
import PropTypes from 'prop-types'
import { withRouter } from "react-router-dom";
import { connect } from "react-redux";
import { makeStyles } from "#material-ui/core/styles";
import TextField from "#material-ui/core/TextField";
import Button from "#material-ui/core/Button";
import {getList,updateList,getUpdatedList} from "./../Action/Action";
export class Payment extends React.Component {
constructor(props) {
super(props);
this.state = {
pickedItem: [1, 2]
};
}
componentWillMount() {
this.props.getUpdatedList();
}
render() {
console.log(this.props)
const { pickedItem } = this.state;
//console.log(pickedItem);
return (
<div className="PaymentPage">
<div className="pageWrapper">
<form noValidate autoComplete="off">
<h1>Payment Details</h1>
<TextField
id="outlined-name"
label="Card Type"
margin="normal"
variant="outlined"
/>
<TextField
id="outlined-name"
label="Card Name"
margin="normal"
variant="outlined"
/>
<TextField
id="outlined-name"
label="Card Number"
margin="normal"
variant="outlined"
/>
<div className="clm-2-inp">
<TextField
id="outlined-name"
label="Expiry Date (MM/YYYY)"
margin="normal"
variant="outlined"
/>
<TextField
id="outlined-name"
label="CVV"
margin="normal"
variant="outlined"
/>
</div>
</form>
<div className="itemsection">
<h2>Summery</h2>
<div className="item-list">
<div className="logoWarapper">
<img
src="https://rukminim1.flixcart.com/image/660/792/jmdrr0w0/shirt/q/q/r/xxl-tblwtshirtful-sh4-tripr-original-imaf9ajwb3mfbhmh.jpeg?q=50"
width="100"
height="100"
alt=""
/>
</div>
<div className="itemWarapper">
<h3>Item Name</h3>
<p>
<span>₹</span>
<span>3000</span>
</p>
</div>
</div>
<Button variant="contained" color="primary">
Submit Purchase
</Button>
</div>
</div>
</div>
);
}
}
Payment.propTypes = {
list: PropTypes.object,
getList: PropTypes.func,
updateList:PropTypes.func,
getUpdatedList:PropTypes.func
}
function mapStateToProps(state,ownProps){
console.log(state,ownProps)
const Items= state
return {
list : Items.list
}
}
const mapDispatchToProps = {
getList,
updateList,
getUpdatedList
};
export default withRouter(connect(
mapStateToProps,
mapDispatchToProps
)(Payment));
Reducer
const initialState = {
list: {}
}
const Reducer = (state = initialState, action) => {
switch (action.type) {
case "GET_LIST_SUCCESS":
return {
...state,
list: action.json,
}
case "GET_LIST_SUCCESS":
return {
...state,
list: action.list,
}
default:
return state;
}
};
export default Reducer;
Once i click the "Make payment" button in the first component, i will updated the list with some modification those modified changes i want to get in the second component.
I unable to get first redux store value in the second component.
Help me to ix this issue please.
I have two components-AskQuestion and SingleQuestion
I want to pass the data from AskQuestion to SingleQuestion. How to make this.state.form content available in SingleQuestion component.
AskQuestion.jsx
import React, { Component } from 'react';
import EditableTagGroup from '../EditableTagGroupComponent/EditableTagGroup';
import { createHashHistory } from 'history'
const history = createHashHistory();
class AskQuestion extends Component {
constructor(props) {
super(props)
this.state = {
form: {
Title: '',
Content: '',
Tags: sessionStorage.getItem("TG"),
}
};
this.onChange = this.onChange.bind(this);
this.changeHandler = this.changeHandler.bind(this);
this.submitHandler = this.submitHandler.bind(this);
}
changeHandler(e) {
e.persist();
let store = this.state;
store.form[e.target.name] = e.target.value;
this.setState(store);
}
submitHandler(e) {
e.preventDefault();
fetch('cons/ques/create', {
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify(
{
"Request": {
"RequestInfo": {
"userId": "2"
},
"RequestPayload": {
"Questions": [
{
"questionId": 0,
"questionTitle": this.state.form.Title,
"isAnswered": false,
"questionContent": this.state.form.Content,
"tags": [{
"tagId": 1,
"tagName": "Java",
"tagUsage": 1
}]
}
]
}
}
}
)
}).then(res => {
console.log(res);
this.redirect();
return res;
}).catch(err => err);
}
redirect = () => {
this.props.history.push('/SingleQuestion');
}
onChange(e) {
this.setState({ [e.target.name]: e.target.value });
}
render() {
const { form } = this.state;
return (
<div className="container">
<h2>ASK A QUESTION</h2>
<form onSubmit={this.submitHandler}>
<div className="form-group">
<label htmlFor="Title">Title:</label>
<input name="Title" type="text" className="form-control" id={this.state.form.Title} placeholder="Enter Title" onChange={this.changeHandler} />
</div>
<div className="form-group">
<label htmlFor="Content">Content:</label>
<textarea type="Content" className="form-control" id={this.state.form.Content} placeholder="Content" name="Content" style={{ height: "300px" }} onChange={this.changeHandler}></textarea>
</div>
<div className="form-group">
<label htmlFor="Tags">Tags:</label>
<EditableTagGroup />
</div>
<button type="submit" className="btn btn-default">Post Question</button>
<button type="submit" className="btn btn-default">Discard</button>
</form>
</div>
)
}
}
export default AskQuestion;
SingleQuestion.jsx
import React, { Component } from 'react';
import './SingleQuestion.css';
class SingleQuestion extends Component {
constructor(props) {
super(props)
this.state = {
};
}
render() {
return (
<div class="question-container col-lg-10">
<div class="question-icons pull-left">
<div class="rating">
<i class="button rating-up fa fa-thumbs-o-up" aria-hidden="true"></i>
<span class="counter">0</span>
<i class="button rating-down fa fa-thumbs-o-down" aria-hidden="true"></i>
</div>
</div>
<div class="result-link pull-left" style={{ paddingLeft: "30px", paddingTop: "55px" }}>
<h1>{this.props.Title}</h1>
</div>
</div>
)
}
}
export default SingleQuestion;
I saw posts like how to share state but didn't help me. mostly i saw something like this
<SingleQuestion callback=*****/>
if I do like that where ever I use this <SingleQuestion ------/> that component will be rendered which i don't want to do. I am new to reactjs please
help me in this..
Thanks in advance!!
This is an example to pass data between parallel components in reactjs
// App.js
import React, { Component } from 'react';
import { Route, Switch, Redirect } from 'react-router-dom';
import SingleQuestion from './SingleQuestion';
import AskQuestion from './AskQuestion';
class App extends Component {
state = {
formData: null
}
callbackFormData = (formData) => {
console.log(formData);
this.setState({formData: formData});
}
render() {
return (
<Switch>
<Route path='/askQuestion' render={() => <AskQuestion callbackFormData={this.callbackFormData}/> } />
<Route path='/singleQuestion' render={() => <SingleQuestion formData={this.state.formData}/>} />
</Switch>
);
}
}
export default App;
//AskQuestion
import React, { Component } from "react";
import { withRouter } from 'react-router-dom';
class AskQuestion extends Component {
redirect = () => {
this.props.history.push("singleQuestion");
};
submitHandler = () => {
let title = document.getElementById('title').value;
if(title !== '')
this.props.callbackFormData(title);
this.redirect();
}
render() {
return (
<React.Fragment>
<input id="title" />
<button onClick={this.submitHandler}>Post Question</button>
</React.Fragment>
)
}
}
export default withRouter(AskQuestion);
// SingleQuestion.js
import React, { Component } from "react";
class SingleQuestion extends Component {
render() {
return <h1>Title:- {this.props.formData}</h1>;
}
}
export default SingleQuestion;
i hope it helps!
If you want to use state form in SingleQuestion component after called redirect, try this.
redirect = () => {
this.props.history.push('/SingleQuestion', {
form: this.state.form
});
}
After then check console.log(this.props.history.location.state.form)
I have this component:
import React, { Component } from 'react';
import { inject, observer } from 'mobx-react';
import PropTypes from 'prop-types';
import './cardCheck.css';
#inject('auto')
#observer
class CardCheck extends Component {
render() {
const { auto } = this.props;
return (
<div>
<div className="newsletter-container">
<h1>Enter the ID of your card:</h1>
<div className="center">
<input type="number" />
<input type="submit" value="Check" onClick={event => {displayInfo}} />
</div>
<div className="results"></div>
</div>
<h1>Offers:</h1>
</div>
);
}
}
CardCheck.propTypes = {
auto: PropTypes.shape({
carCount: PropTypes.number
})
};
CardCheck.wrappedComponent.defaultProps = {
auto: autoPropTypeDefaults
};
export default CardCheck;
I want to make so that when someone clicks the input with value Check the div below with the className of results to be populated with my data from the store:
import { observable, action, computed } from 'mobx';
class Auto {
#observable
auto = [
{
name: 'Shop1'
},
{
name: 'Shop2'
}
];
#action
displayInfo() {
}
}
export { Auto };
I tried to make the displayInfo function iterate through the array with objects with a map from loadash but it didn't work, it did not displayed the data inside the div, how can I do this?
You can add an observable field on your CardCheck component that you toggle with the onClick event handler, and when the field is true you can display all entries in the auto array.
Example
class CardCheck extends Component {
#observable
checked = false;
onClick = event => {
event.preventDefault();
this.checked = !this.checked;
};
render() {
const { auto } = this.props;
return (
<div>
<div className="newsletter-container">
<h1>Enter the ID of your card:</h1>
<div className="center">
<input type="number" />
<input type="submit" value="Check" onClick={this.onClick} />
</div>
<div className="results">
{this.checked &&
auto.auto.map((a, index) => <div key={index}>{a.name}</div>)}
</div>
</div>
<h1>Offers:</h1>
</div>
);
}
}
I'm trying to populate an array of object in my state when my component loads. I have the following files. What I want to happen is that my caseList state gets updated and after calling the loadCases method from my mockapi. The problem is it seems like I can't seem to get the values from my mockapi. I'm pretty new to react and redux so I might have missed a very key concept here.
CaseListPage.js
import React, {PropTypes} from 'react';
import {connect} from 'react-redux';
import BulletImage from '../../images/icon_requestor.png';
import {IndexLink} from 'react-router';
import CaseListHeader from './CaseListHeader';
import * as caseActions from '../../actions/caseActions';
import {bindActionCreators} from 'redux';
import CaseItems from './CaseItems';
class CaseListPage extends React.Component {
constructor(props, context) {
super(props, context);
this.state = {
caseList: []
};
}
componentDidMount() {
this.props.actions.loadCases()
.then((response) => console.log(response));
}
render() {
return(
<div className="container-fluid">
<div className="row">
<div className="col-xs-6 form-header-container">
<img src={BulletImage} alt="bullets" className="bulletImage pull-left" width="40"/>
<span className="form-header-cl pull-left">LIST OF REQUESTS LOGGED</span>
</div>
<div className="col-xs-6" id="backDiv">
<IndexLink to="/">
<p className="form-header-back pull-right">
<i className="glyphicon glyphicon-chevron-left" aria-hidden="true"></i>
BACK
</p>
</IndexLink>
</div>
</div>
<CaseListHeader />
<div className="row case-list-items">
{/*<CaseItems items={this.state.caseList}/>*/}
<div id="caseListItem1" className="row collapse case-list-request">
<div className="col-xs-2">
<span> </span>
<span className="case-id-item">LEMUEL MALLARI</span>
</div>
<div className="col-xs-3">
<span> </span>
<span>Request ID: R10000001</span>
</div>
<div className="col-xs-2">
<span> </span>
<span>22/07/2018 01:00</span>
</div>
<div className="col-xs-3">
<span> </span>
<span>CPO: In Progress</span>
</div>
<div className="col-xs-1">
<button type="button" className="btn btn-case-item">RECALL</button>
</div>
<div className="col-xs-1">
<button type="button" className="btn btn-case-item">TRACK</button>
</div>
</div>
</div>
</div>
);
}
}
function mapDispatchToProps(dispatch) {
return {
actions: bindActionCreators(caseActions, dispatch)
};
}
function mapStateToProps(state, ownProps) {
return {
cases: state.cases
};
}
CaseListPage.propTypes = {
actions: PropTypes.object.isRequired,
cases: PropTypes.arrayOf(PropTypes.object)
};
export default connect(mapStateToProps, mapDispatchToProps)(CaseListPage);
caseActions.js
import * as types from './actionTypes';
import caseApi from '../api/mockCaseAPI';
import {beginAjaxCall, ajaxCallError} from './ajaxStatusActions';
export function loadCasesSuccess(cases) {
return { type: types.LOAD_CASES_SUCCESS, cases };
}
export function loadCases() {
return function(dispatch) {
dispatch(beginAjaxCall());
return caseApi.getAllCases().then(cases => {
dispatch(loadCasesSuccess(cases));
}).catch(error => {
throw(error);
});
};
}
caseReducer.js
import * as types from '../actions/actionTypes';
import initialState from './initialState';
export default function caseReducer(state = initialState.cases, action) {
switch (action.type) {
case types.LOAD_CASES_SUCCESS:
return action.cases;
default:
return state;
}
}
mockCaseApi.js:
import delay from './delay';
const cases = [
{
caseid: '709460',
requestname: 'iPhone Request',
lastmodified: '20/07/2018 05:34',
overallstatus: 'CPO: In Progress',
requests: ['#caseListItem1', '#caseListItem2', '#caseListItem3']
},
{
caseid: '709461',
requestname: 'iPad Request',
lastmodified: '22/07/2018 05:34',
overallstatus: 'Completed',
requests: ['#caseListItem3', '#caseListItem5', '#caseListItem6']
},
{
caseid: '709462',
requestname: 'iPhone Request',
lastmodified: '25/07/2018 05:34',
overallstatus: 'CPO: In Progress',
requests: ['#caseListItem7', '#caseListItem8', '#caseListItem9']
}
];
class CaseAPI {
static getAllCases() {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve(Object.assign([], cases));
}, delay);
});
}
}
export default CaseAPI;
configureStore.dev.js
import { createStore, applyMiddleware } from 'redux';
import rootReducer from '../reducers';
import reduxImmutableStateInvariant from 'redux-immutable-state-invariant';
import thunk from 'redux-thunk';
export default function configureStore(initialState) {
return createStore(
rootReducer,
initialState,
applyMiddleware(thunk, reduxImmutableStateInvariant())
);
}
I don't think you are using bindActionCreators correctly, from the redux docs:
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.
Instead write your mapDispatchToProps like:
import { loadCases } from '../../actions/caseActions';
...
...
componentDidMount() {
this.props.loadCases()
.then((response) => console.log(response));
}
...
function mapDispatchToProps(dispatch) {
return {
loadCases: () => dispatch(loadCases())
};
}
I am using redux and react-redux.
I have a huge list of data which are the occupations of a user.
I have this container that is connected to the redux via connect of react-redux.
// ChangeOccupations.js
import React, { Component } from 'react';
import { connect } from 'react-redux';
import ChangeOccupation from '../../../../components/pages/admin/subs/ChangeOccupation';
import {
occupation_update
} from '../../../../actions/edit';
class ChangeOccupations extends Component {
render() {
let occupations = this.props.occupations.map((occupation, i) => <ChangeOccupation occupation={occupation} original={occupation} index={i} key={i} occupationUpdate={this.props.occupationUpdate} />);
return (
<div>
<p className="title">Change Your Occupations</p>
{occupations}
</div>
);
}
}
function mapStateToProps(store) {
return {
occupations: store.edit.occupations
}
}
function mapDispatchToProps(dispatch) {
return {
occupationUpdate: payload => dispatch(occupation_update(payload))
}
}
export default connect(mapStateToProps, mapDispatchToProps)(ChangeOccupations);
then a component.
// ChangeOccupation.js
import React, { Component } from 'react';
class ChangeOccupation extends Component {
constructor(props) {
super(props);
this.changeCompany = this.changeCompany.bind(this);
this.changeFreelance = this.changeFreelance.bind(this);
}
changeCompany(event) {
let value = event.target.value;
this.props.occupationUpdate({
index: this.props.index,
occupation: {
...this.props.occupation,
company: value
}
});
}
changeFreelance() {
console.log(this.props.occupation.freelance);
if(this.props.occupation.freelance == 1) {
return this.props.occupationUpdate({
index: this.props.index,
occupation: {
...this.props.occupation,
freelance: 0
}
});
}
return this.props.occupationUpdate({
index: this.props.index,
occupation: {
...this.props.occupation,
freelance: 1
}
});
}
render() {
console.log(this.props.occupationUpdate);
return (
<form method="post" action="">
<ul className="ul-blocked-li">
<li><input type="text" placeholder="Company name..." value={this.props.occupation.company? this.props.occupation.company: ''} onChange={this.changeCompany} /></li>
<li><input type="text" placeholder="Job title..." value={this.props.occupation.title} onChange={this.changeCompany} /></li>
<li>
<input type="hidden" value={this.props.occupation.freelance} />
<input id="freelance" type="checkbox" onChange={this.changeFreelance} />
<label htmlFor="freelance">I am a freelancer</label>
</li>
</ul>
</form>
);
}
}
export default ChangeOccupation;
so the container is connected to redux and it will receive all the occupations data and the dispatches. It will then render all the occupations data via the this.props.occupations.map() using the <ChangeOccupation /> component which will receive all the props and dispatches, you can see it on this line:
let occupations = this.props.occupations.map((occupation, i) => <ChangeOccupation occupation={occupation} original={occupation} index={i} key={i} />);
the problem is that when the <ChangeOccupation/> component dispatches an action it doesn't seem to update or anything, but it does reach the reducer. What could be the possible problems?