即使在redux状态更新后,mapStateToProps也不会将更新的prop返回到react

时间:2018-11-18 11:50:49

标签: reactjs redux react-redux

我是redux的新手。我正在尝试将redux与我的react项目集成在一起。 我面临的问题是,即使状态在React存储库中进行了更新,提供给组件的mapStateToProps函数也不会返回更新的props.reduce函数会返回正确的函数。而且mapDispatchToProps函数也可以正常工作。 下面是我的代码。 //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 个答案:

答案 0 :(得分:2)

设置newState的方式不是问题吗?

代替

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

尝试

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

那样,newState将成为一个新对象

答案 1 :(得分:0)

一个可能的原因是您试图将mapStateToProps连接到一个哑组件(在您的情况下为QuestionPaginationGroup)。我不确定它是否以这种方式工作。即使这样做,也违反official Redux recommendations。因此,您可以尝试将QuestionPaginationGroupconst转换为成熟的类组件(class QuestionPaginationGroup extends React.component)以使其正常工作