React Redux 测验
2019-10-07
944
我正尝试按照 https://www.codeproject.com/Articles/5130417/Quiz-Application-in-React-Using-Redux 中的示例,使用 Redux 制作一个简单的测验。不知何故,我认为 quizLoad Reducer 没有获取数据,甚至没有被正确调用。
这是我的 Reducer:
const QUIZ_LOAD = 'QUIZ_LOAD';
const QUIZ_ANSWER = 'QUIZ_ANSWER';
const QUIZ_SUBMIT = 'QUIZ_SUBMIT';
const PAGER_UPDATE = 'PAGER_UPDATE';
const INITIAL_STATE = {
quiz: {
config: {
'allowBack': false,
'allowReview': false,
'autoMove': true, // if true, it will move to next question automatically when answered.
'duration': 0, // indicates the time in which quiz needs to be completed. 0 means unlimited.
'pageSize': 1,
'requiredAll': false, // indicates if you must answer all the questions before submitting.
'richText': false,
'shuffleQuestions': false,
'shuffleOptions': false,
'showClock': false,
'showPager': true,
'theme': 'none'
},
questions: []
},
mode: 'quiz',
pager: {
index: 0,
size: 1,
count: 1
}
}
export default (state = INITIAL_STATE, action) => {
const { type, payload } = action;
console.log('REDUCERRRRRRRRR')
switch (type) {
case PAGER_UPDATE:
return { ...state, pager: payload, mode: 'quiz' };
case QUIZ_LOAD:
return { ...state, quiz: payload };
case QUIZ_SUBMIT:
return { ...state, mode: payload };
case QUIZ_ANSWER:
return { ...state, quiz: payload };
default:
return state;
}
};
// <<<ACTIONS>>>
export const pagerUpdate = (payload) => {
return {
type: PAGER_UPDATE,
pager: payload,
mode: 'quiz'
};
};
export const quizLoad = (payload) => {
return {
type: QUIZ_LOAD,
quiz: payload
};
};
export const quizSubmit = (payload) => {
return {
type: QUIZ_SUBMIT,
mode: { payload }
};
};
export const quizAnswer = (payload) => {
return {
type: QUIZ_ANSWER,
quiz: { payload }
}
};
这是我的组件,也是我出现错误的地方
"Unhandled Rejection (TypeError): Cannot read property 'config' of undefined eval C:\Users\Willkommen\Documents\MyPension\REPOs\web-best\src\pages\header\vertragsCheck\index.js:69:6"
import React from "react";
import { connect } from "react-redux";
import Quiz from "./quiz/Quiz";
import {
pagerUpdate,
quizLoad
} from "redux/vertragsCheck/vertragscheckReducer";
import SEOTitle from "components/SEO/seoTitle";
import WavySectionWrapper from "components/Layouts/Containers/wavySectionWrapper/wavySectionWrapper";
import WavyPageTitleWrapper from "components/Sections/WavyPageTitle/WavyPageTitle";
import Button from "components/Button/Button";
import "./vertragsCheckSteps.scss";
const bgMobileImage =
"/images/illustrations/pages/Home/mobile/mobile-phone1.png";
class vertragsCheck extends React.Component {
state = {
// quizes: [
// { id: 'data/myPensionQuiz.json', name: 'VertragsCheck' },
// { id: 'data/myPensionTest.json', name: 'Rente' }
// ],
quizVisible: false,
quizId: "quizApi/quiz.json"
};
pager = {
index: 0,
size: 1,
count: 1
};
componentDidMount() {
this.load(this.state.quizId);
}
load(quizId) {
let url = quizId || this.props.quizId;
fetch(`../${url}`)
.then(res => res.json())
.then(res => {
let quiz = res;
quiz.questions.forEach(q => {
q.options.forEach(o => (o.selected = false));
});
debugger;
console.log("quizCONFIG", this.props.quiz);
quiz.config = Object.assign(this.props.quiz.config || {}, quiz.config);
this.pager.count = quiz.questions.length / this.pager.size;
this.props.onQuizLoad(quiz);
this.props.onPagerUpdate(this.pager);
});
}
// onChange = (e) => {
// this.setState({ quizId: e.target.value });
// this.load(e.target.value);
// }
handleClick = () => {
const { quizVisible } = this.state;
this.setState({ quizVisible: !quizVisible });
};
render() {
const quizVisible = this.state.quizVisible;
if (!quizVisible) {
return (
<WavySectionWrapper vertical>
<SEOTitle page="vertrags-check" />
<WavyPageTitleWrapper>
<div className="flex-container">
<div>
<h1>
Kostenloser <br />
Vertrags-Check
</h1>
<p>
Ist meine bestehender Vertrag zu teuer? <br />
Wie schneidet meine bestehen Altervorsorge ab? <br />
Wir helfen Dir Deine Altervorsorge zu optimieren.
</p>
<Button size="sm" onClick={this.handleClick}>
Jetzt prüfen
</Button>
</div>
<div>
<img src={bgMobileImage} alt="myPension mobile graphic" />
{/* <img
src="/images/background-elements/bg-vertical-section.svg"
/> */}
</div>
</div>
</WavyPageTitleWrapper>
</WavySectionWrapper>
);
} else if (quizVisible) {
return (
<Quiz
quiz={this.state.quiz}
quizId={this.state.quizId}
mode={this.state.mode}
/>
);
}
}
}
const mapStateToProps = state => {
return { ...state.quiz };
};
const mapDispatchToProps = dispatch => ({
onQuizLoad: payload => dispatch({ type: quizLoad, payload }),
onPagerUpdate: payload => dispatch({ type: pagerUpdate, payload })
});
export default connect(
mapStateToProps,
mapDispatchToProps
)(vertragsCheck);
这是我在公共文件夹中的测验数据:
{
"id": 1,
"name": "Vertrags-check Quiz",
"description": "Vertrags-check Quiz determines if your actual pension contract is improvable",
"config": {
"showPager": false,
"allowBack": true,
"autoMove": true
},
"questions": [
{
"id": 1010,
"name": "Sind die Effektivkosten höher als 1,5%?",
"questionTypeId": 1,
"options": [
{
"id": 1055,
"questionId": 1010,
"name": "Ja",
"isAnswer": false
},
{
"id": 1056,
"questionId": 1010,
"name": "Nein",
"isAnswer": false
},
{
"id": 1057,
"questionId": 1010,
"name": "Weiß nicht",
"isAnswer": true
}
],
"questionType": {
"id": 1,
"name": "test type",
"isActive": true
}
},
{
"id": 1011,
"name": "Liegt Dein Rentenfaktor unter 27€?",
"questionTypeId": 1,
"options": [
{
"id": 1055,
"questionId": 1010,
"name": "Ja",
"isAnswer": false
},
{
"id": 1056,
"questionId": 1010,
"name": "Nein",
"isAnswer": false
},
{
"id": 1057,
"questionId": 1010,
"name": "Weiß nicht",
"isAnswer": true
}
],
"questionType": {
"id": 1,
"name": "test type",
"isActive": true
}
},
{
"id": 1012,
"name": "Erfolgt die Anlage zu weniger als 80% in Aktien?",
"questionTypeId": 1,
"options": [
{
"id": 1055,
"questionId": 1010,
"name": "Ja",
"isAnswer": false
},
{
"id": 1056,
"questionId": 1010,
"name": "Nein",
"isAnswer": false
},
{
"id": 1057,
"questionId": 1010,
"name": "Weiß nicht",
"isAnswer": true
}
],
"questionType": {
"id": 1,
"name": "test type",
"isActive": true
}
},
{
"id": 1013,
"name": "Ist Deine Rendite geringer als 3% p.A.?",
"questionTypeId": 1,
"options": [
{
"id": 1055,
"questionId": 1010,
"name": "Ja",
"isAnswer": false
},
{
"id": 1056,
"questionId": 1010,
"name": "Nein",
"isAnswer": false
},
{
"id": 1057,
"questionId": 1010,
"name": "Weiß nicht",
"isAnswer": true
}
],
"questionType": {
"id": 1,
"name": "test type",
"isActive": true
}
},
{
"id": 1014,
"name": "Zahlst Du für Flexibilität?",
"questionTypeId": 1,
"options": [
{
"id": 1055,
"questionId": 1010,
"name": "Ja",
"isAnswer": false
},
{
"id": 1056,
"questionId": 1010,
"name": "Nein",
"isAnswer": false
},
{
"id": 1057,
"questionId": 1010,
"name": "Weiß nicht",
"isAnswer": true
}
],
"questionType": {
"id": 1,
"name": "test type",
"isActive": true
}
},
{
"id": 1015,
"name": "Es gibt keine Steuervorteile bei deinem bestehendem Vertrag?",
"questionTypeId": 1,
"options": [
{
"id": 1055,
"questionId": 1010,
"name": "Ja",
"isAnswer": false
},
{
"id": 1056,
"questionId": 1010,
"name": "Nein",
"isAnswer": false
},
{
"id": 1057,
"questionId": 1010,
"name": "Weiß nicht",
"isAnswer": true
}
],
"questionType": {
"id": 1,
"name": "test type",
"isActive": true
}
},
{
"id": 1016,
"name": "Hast Du Deinen Vertrag nach 2005 abgeschlossen?",
"questionTypeId": 1,
"options": [
{
"id": 1055,
"questionId": 1010,
"name": "Ja",
"isAnswer": false
},
{
"id": 1056,
"questionId": 1010,
"name": "Nein",
"isAnswer": false
},
{
"id": 1057,
"questionId": 1010,
"name": "Weiß nicht",
"isAnswer": true
}
],
"questionType": {
"id": 1,
"name": "test type",
"isActive": true
}
}
]
}
1个回答
这里可能存在问题:
const mapStateToProps = state => { return { ...state.quiz } };
您正在使用对象扩展运算符,它将 state.quiz 的内容放入/映射到您的 props 中。因此
this.props
中没有任何
quiz
。
尝试以这种方式将
state.quiz
映射到
this.props.quiz
:
const mapStateToProps = state => { return { quiz: state.quiz } };
您还错误地将操作映射到 props,请尝试此操作:
const mapDispatchToProps = dispatch => ({
onQuizLoad: payload => dispatch(quizLoad(payload)),
onPagerUpdate: payload => dispatch(pagerUpdate(payload))
});
lavor
2019-10-07