我是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;
答案 0 :(得分:2)
设置newState的方式不是问题吗?
代替
newState = Object.assign(state, ...)
尝试
newState = Object.assign({}, state, ...)
那样,newState将成为一个新对象
答案 1 :(得分:0)
一个可能的原因是您试图将mapStateToProps连接到一个哑组件(在您的情况下为QuestionPaginationGroup
)。我不确定它是否以这种方式工作。即使这样做,也违反official Redux recommendations。因此,您可以尝试将QuestionPaginationGroup
从const
转换为成熟的类组件(class QuestionPaginationGroup extends React.component
)以使其正常工作