0
votes

I'm new to redux. I am trying to integrate redux with my react project. I'm facing problem that even the state is updated inside the react store, the mapStateToProps function supplied to component is not returning updated props.The reducer function is returning the correct function. And mapDispatchToProps function is also working fine. Below is my code. //QuestionPagination.js

import React, { Component } from 'react';
import {Table} from 'semantic-ui-react';
import {setNewActiveIndex} from '../actions/index';
import {connect} from 'react-redux';

/*
required props
activeIndex={this.state.currentQuestionIndex}
function setActiveIndex actionDispatcher
unAttemptedQuestions={this.state.unAttemptedQuestions}
*/

const mapDispatchToProps = (dispatch)=>{
  return {
    setActiveIndex: (index)=>dispatch(setNewActiveIndex(index))
  };
}

const mapStateToProps = state=>{
  return {
    activeIndex: state.currentQuestionIndex,
    unAttemptedQuestions: state.unAttemptedQuestions
  }
}

const QuestionPaginationGroup=(props)=>{

  function onClickHandler(e){
    console.log('setting active index value: ', e);
    props.setActiveIndex(e);
  }

  console.log('current props: ', JSON.stringify(props));

      return (<Table celled selectable>

      <Table.Body>

        <Table.Row>
          <Table.Cell error={props.unAttemptedQuestions.indexOf(0)==-1 
 ? false : true } active={props.activeIndex==0 ? true : false} 
onClick={()=>onClickHandler(0)}>1</Table.Cell>
          <Table.Cell error={props.unAttemptedQuestions.indexOf(1)==-1 
? false : true } active={props.activeIndex==1 ? true : false} onClick= 
{()=>onClickHandler(1)}>2</Table.Cell>
          <Table.Cell error={props.unAttemptedQuestions.indexOf(2)==-1 
? false : true } active={props.activeIndex==2 ? true : false} onClick= 
{()=>onClickHandler(2)}>3</Table.Cell>
          <Table.Cell error={props.unAttemptedQuestions.indexOf(3)==-1 
? false : true } active={props.activeIndex==3 ? true : false} onClick= 
{()=>onClickHandler(3)}>4</Table.Cell>
          <Table.Cell error={props.unAttemptedQuestions.indexOf(4)==-1 
 ? false : true } active={props.activeIndex==4 ? true : false} 
onClick={()=>onClickHandler(4)}>5</Table.Cell>
        </Table.Row>

        <Table.Row>
          <Table.Cell error={props.unAttemptedQuestions.indexOf(5)==-1 
 ? false : true } active={props.activeIndex==5 ? true : false} 
 onClick={()=>onClickHandler(5)}>6</Table.Cell>
          <Table.Cell error={props.unAttemptedQuestions.indexOf(6)==-1 
? false : true } active={props.activeIndex==6 ? true : false} onClick= 
{()=>onClickHandler(6)}>7</Table.Cell>
          <Table.Cell error={props.unAttemptedQuestions.indexOf(7)==-1 
? false : true } active={props.activeIndex==7 ? true : false} onClick= 
{()=>onClickHandler(7)}>8</Table.Cell>
          <Table.Cell error={props.unAttemptedQuestions.indexOf(8)==-1 
? false : true } active={props.activeIndex==8 ? true : false} onClick= 
{()=>onClickHandler(8)}>9</Table.Cell>
          <Table.Cell error={props.unAttemptedQuestions.indexOf(9)==-1 
? false : true } active={props.activeIndex==9 ? true : false} onClick= 
{()=>onClickHandler(9)}>10</Table.Cell>
        </Table.Row>

        <Table.Row>
          <Table.Cell error= 
{props.unAttemptedQuestions.indexOf(10)==-1 ? false : true } active= 
{props.activeIndex==10 ? true : false} onClick= 
{()=>onClickHandler(10)}>11</Table.Cell>
          <Table.Cell error= 
 {props.unAttemptedQuestions.indexOf(11)==-1 ? false : true } active= 
 {props.activeIndex==11 ? true : false} onClick= 
 {()=>onClickHandler(11)}>12</Table.Cell>
           <Table.Cell error= 
 {props.unAttemptedQuestions.indexOf(12)==-1 ? false : true } active= 
 {props.activeIndex==12 ? true : false} onClick={()=>onClickHandler(12)}>13</Table.Cell>
      <Table.Cell error={props.unAttemptedQuestions.indexOf(13)==-1 ? false : true } active={props.activeIndex==13 ? true : false} onClick={()=>onClickHandler(13)}>14</Table.Cell>
      <Table.Cell error={props.unAttemptedQuestions.indexOf(14)==-1 ? false : true } active={props.activeIndex==14 ? true : false} onClick={()=>onClickHandler(14)}>15</Table.Cell>
    </Table.Row>

    <Table.Row>
      <Table.Cell error={props.unAttemptedQuestions.indexOf(15)==-1 ? false : true } active={props.activeIndex==15 ? true : false} onClick={()=>onClickHandler(15)}>16</Table.Cell>
      <Table.Cell error={props.unAttemptedQuestions.indexOf(16)==-1 ? false : true } active={props.activeIndex==16 ? true : false} onClick={()=>onClickHandler(16)}>17</Table.Cell>
      <Table.Cell error={props.unAttemptedQuestions.indexOf(17)==-1 ? false : true } active={props.activeIndex==17 ? true : false} onClick={()=>onClickHandler(17)}>18</Table.Cell>
      <Table.Cell error={props.unAttemptedQuestions.indexOf(18)==-1 ? false : true } active={props.activeIndex==18 ? true : false} onClick={()=>onClickHandler(18)}>19</Table.Cell>
      <Table.Cell error={props.unAttemptedQuestions.indexOf(19)==-1 ? false : true } active={props.activeIndex==19 ? true : false} onClick={()=>onClickHandler(19)}>20</Table.Cell>
    </Table.Row>

    <Table.Row>
      <Table.Cell error={props.unAttemptedQuestions.indexOf(20)==-1 ? false : true } active={props.activeIndex==20 ? true : false} onClick={()=>onClickHandler(20)}>21</Table.Cell>
      <Table.Cell error={props.unAttemptedQuestions.indexOf(21)==-1 ? false : true } active={props.activeIndex==21 ? true : false} onClick={()=>onClickHandler(21)}>22</Table.Cell>
      <Table.Cell error={props.unAttemptedQuestions.indexOf(22)==-1 ? false : true } active={props.activeIndex==22 ? true : false} onClick={()=>onClickHandler(22)}>23</Table.Cell>
      <Table.Cell error={props.unAttemptedQuestions.indexOf(23)==-1 ? false : true } active={props.activeIndex==23 ? true : false} onClick={()=>onClickHandler(23)}>24</Table.Cell>
      <Table.Cell error={props.unAttemptedQuestions.indexOf(24)==-1 ? false : true } active={props.activeIndex==24 ? true : false} onClick={()=>onClickHandler(24)}>25</Table.Cell>
    </Table.Row>

    <Table.Row>
      <Table.Cell error={props.unAttemptedQuestions.indexOf(25)==-1 ? false : true } active={props.activeIndex==25 ? true : false} onClick={()=>onClickHandler(25)}>26</Table.Cell>
      <Table.Cell error={props.unAttemptedQuestions.indexOf(26)==-1 ? false : true } active={props.activeIndex==26 ? true : false} onClick={()=>onClickHandler(26)}>27</Table.Cell>
      <Table.Cell error={props.unAttemptedQuestions.indexOf(27)==-1 ? false : true } active={props.activeIndex==27 ? true : false} onClick={()=>onClickHandler(27)}>28</Table.Cell>
      <Table.Cell error={props.unAttemptedQuestions.indexOf(28)==-1 ? false : true } active={props.activeIndex==28 ? true : false} onClick={()=>onClickHandler(28)}>29</Table.Cell>
      <Table.Cell error={props.unAttemptedQuestions.indexOf(29)==-1 ? false : true } active={props.activeIndex==29 ? true : false} onClick={()=>onClickHandler(29)}>30</Table.Cell>
    </Table.Row>

    <Table.Row>
      <Table.Cell error={props.unAttemptedQuestions.indexOf(30)==-1 ? false : true } active={props.activeIndex==30 ? true : false} onClick={()=>onClickHandler(30)}>31</Table.Cell>
      <Table.Cell error={props.unAttemptedQuestions.indexOf(31)==-1 ? false : true } active={props.activeIndex==31 ? true : false} onClick={()=>onClickHandler(31)}>32</Table.Cell>
      <Table.Cell error={props.unAttemptedQuestions.indexOf(32)==-1 ? false : true } active={props.activeIndex==32 ? true : false} onClick={()=>onClickHandler(32)}>33</Table.Cell>
      <Table.Cell error={props.unAttemptedQuestions.indexOf(33)==-1 ? false : true } active={props.activeIndex==33 ? true : false} onClick={()=>onClickHandler(33)}>34</Table.Cell>
      <Table.Cell error={props.unAttemptedQuestions.indexOf(34)==-1 ? false : true } active={props.activeIndex==34 ? true : false} onClick={()=>onClickHandler(34)}>35</Table.Cell>
    </Table.Row>

    <Table.Row>
      <Table.Cell error={props.unAttemptedQuestions.indexOf(35)==-1 ? false : true } active={props.activeIndex==35 ? true : false} onClick={()=>onClickHandler(35)}>36</Table.Cell>
      <Table.Cell error={props.unAttemptedQuestions.indexOf(36)==-1 ? false : true } active={props.activeIndex==36 ? true : false} onClick={()=>onClickHandler(36)}>37</Table.Cell>
      <Table.Cell error={props.unAttemptedQuestions.indexOf(37)==-1 ? false : true } active={props.activeIndex==37 ? true : false} onClick={()=>onClickHandler(37)}>38</Table.Cell>
      <Table.Cell error={props.unAttemptedQuestions.indexOf(38)==-1 ? false : true } active={props.activeIndex==38 ? true : false} onClick={()=>onClickHandler(38)}>39</Table.Cell>
      <Table.Cell error={props.unAttemptedQuestions.indexOf(39)==-1 ? false : true } active={props.activeIndex==39 ? true : false} onClick={()=>onClickHandler(39)}>40</Table.Cell>
    </Table.Row>

    <Table.Row>
      <Table.Cell error={props.unAttemptedQuestions.indexOf(40)==-1 ? false : true } active={props.activeIndex==40 ? true : false} onClick={()=>onClickHandler(40)}>41</Table.Cell>
      <Table.Cell error={props.unAttemptedQuestions.indexOf(41)==-1 ? false : true } active={props.activeIndex==41 ? true : false} onClick={()=>onClickHandler(41)}>42</Table.Cell>
      <Table.Cell error={props.unAttemptedQuestions.indexOf(42)==-1 ? false : true } active={props.activeIndex==42 ? true : false} onClick={()=>onClickHandler(42)}>43</Table.Cell>
      <Table.Cell error={props.unAttemptedQuestions.indexOf(43)==-1 ? false : true } active={props.activeIndex==43 ? true : false} onClick={()=>onClickHandler(43)}>44</Table.Cell>
      <Table.Cell error={props.unAttemptedQuestions.indexOf(44)==-1 ? false : true } active={props.activeIndex==44 ? true : false} onClick={()=>onClickHandler(44)}>45</Table.Cell>
    </Table.Row>

    <Table.Row>
      <Table.Cell error={props.unAttemptedQuestions.indexOf(45)==-1 ? 
  false : true } active={props.activeIndex==45 ? true : false} 
 onClick={()=>onClickHandler(45)}>46</Table.Cell>
          <Table.Cell error= 
{props.unAttemptedQuestions.indexOf(46)==-1 ? false : true } active= 
{props.activeIndex==46 ? true : false} onClick= 
{()=>onClickHandler(46)}>47</Table.Cell>
          <Table.Cell error= 
 {props.unAttemptedQuestions.indexOf(47)==-1 ? false : true } active= 
 {props.activeIndex==47 ? true : false} onClick= 
 {()=>onClickHandler(47)}>48</Table.Cell>
          <Table.Cell error= 
{props.unAttemptedQuestions.indexOf(48)==-1 ? false : true } active= 
{props.activeIndex==48 ? true : false} onClick= 
{()=>onClickHandler(48)}>49</Table.Cell>
          <Table.Cell error= 
{props.unAttemptedQuestions.indexOf(49)==-1 ? false : true } active= 
{props.activeIndex==49 ? true : false} onClick= 
{()=>onClickHandler(49)}>50</Table.Cell>
        </Table.Row>

      </Table.Body>
    </Table>)  
  }

  const QuestionPagination = connect(mapStateToProps, 
mapDispatchToProps)(QuestionPaginationGroup);

export default QuestionPagination;

//reducers.js

import {GET_TEST_DATA, SET_NEW_ACTIVE_INDEX, 
     SET_CURRENT_QUESTION_SELECTED_OPTION, 
  SET_QUESTION_ATTEMPTED_OR_UNATTEMPTED_STATUS} from 
 '../constants/action-types';
import  fetchData from '../services/getTestData';


const initialState = {
        questions: [], 
        currentQuestionIndex: 0, 
        unAttemptedQuestions: [],
        isCurrentQuestionAttemped: true,
        answers:{},
        isTestSubmitted: false
            }

 const rootReducer = (state=initialState, action)=>{

    console.log('inside the rootReducer');

    let newState = '';

    switch(action.type){
        case GET_TEST_DATA:
            // const data = await fetchData();

            console.log('returning test data');
            const data = [
                {
                     "id": 1,
                     "ques": "Can you hear what he is .......?",
                     "opt1": "saying",
                     "opt2": "speaking",
                     "opt3": "telling",
                     "opt4": "talking",
                     "opt5": "None of these",
                     "ans": "saying",
                    "body": null
                },
                {
                     "id": 2,
                    "ques": "She hasn't come home ........",
                    "opt1": "still",
                    "opt2": "already",
                    "opt3": "yet",
                    "opt4": "till",
                    "opt5": "None of theses",
                    "ans": "yet",
                    "body": null
                }
            ];
            newState = Object.assign(state, {questions:data});

            console.log('new state from the reducer: ', 
JSON.stringify(newState));
            return newState;
        break;

        case SET_NEW_ACTIVE_INDEX:
            if(state.questions.length>action.payload.index){

            console.log('setActiveIndex called: ');
            console.log('state from the reducer: ', 
JSON.stringify(state));

            const isCurrentQuestionAttemped= 
state.unAttemptedQuestions.indexOf(action.payload.index)==-1 ? true: 
false;
            console.log('isCurrentQuestionAttemped: ', 
isCurrentQuestionAttemped);

            newState = Object.assign(state,
                 {currentQuestionIndex: action.payload.index, 
isCurrentQuestionAttemped: isCurrentQuestionAttemped});
                 console.log('setting new active index: ', 
action.payload.index);
            return newState;
            }
            console.log('new active index can\'t be set');
            return state;

        break;

        case SET_CURRENT_QUESTION_SELECTED_OPTION:
        console.log(`inside the saveCurrentQuestionSelectedOption 
${action.payload.index} and ${action.payload.value}: `);
             newState = Object.assign({}, state);
             newState.answers[action.payload.index] = 
 action.payload.value; 
             return newState;

        break;

        case SET_QUESTION_ATTEMPTED_OR_UNATTEMPTED_STATUS:
            const unAttemptedQuestions = state.unAttemptedQuestions;

            console.log('current state: ', JSON.stringify(state));

            if(state.isCurrentQuestionAttemped){
                unAttemptedQuestions.push(state.currentQuestionIndex);
                newState = Object.assign(state, 
{unAttemptedQuestions:unAttemptedQuestions,isCurrentQuestionAttemped: 
false});
            }
            else{
                unAttemptedQuestions.splice(state.activeIndex, 1);
                newState = Object.assign(state, 
 {unAttemptedQuestions:unAttemptedQuestions, 
 isCurrentQuestionAttemped:true});
            }
            return newState;
         break;

        default:
            return state;
    }
  };

 export default rootReducer;

//store.js

import { createStore } from "redux";
import rootReducer from "../reducers/index";
const store = createStore(rootReducer);
export default store;
2
Can you make a CodeSandbox?Colin Ricardo
The link you gave there doesn't seem to have your app set up.Colin Ricardo

2 Answers

2
votes

isn't the problem the way you set the newState?

instead of

newState = Object.assign(state, ...)

try

newState = Object.assign({}, state, ...)

that way the newState will be a new object

0
votes

One possibe reason is that you're trying to wire mapStateToProps to a dumb component (in you case QuestionPaginationGroup). I'm not sure It works this way. Even if it does, it's against official Redux recommendations. So you can try to convert QuestionPaginationGroup to from const to a full-fldedged class component (class QuestionPaginationGroup extends React.component) to get it working