我试图映射一个由if-else语句的控件呈现的数组,但是我想在该if-else语句中调用一个函数,但是它不起作用。为什么?
import PropTypes from "prop-types";
import { connect } from "react-redux";
import { NavLink } from "react-router-dom";
import { getQuiz, sendResponse } from "../../actions/quizzes";
import Navbar from "../layout/navbar";
class QuizDetail extends Component {
constructor(props) {
super(props);
this.state = {
currentStep: 0,
selectedOption: null,
questionId: null
};
}
static propTypes = {
user: PropTypes.object.isRequired,
quiz: PropTypes.object,
getQuiz: PropTypes.func.isRequired,
sendResponse: PropTypes.func.isRequired
};
onSubmit = e => {
e.preventDefault();
console.log("boulevard");
};
_setQuestion = questionId => {
console.log("me");
this.setState({ questionId });
};
handleOptionChange = changeEvent => {
this.setState({
selectedOption: parseInt(changeEvent.target.id, 10)
});
};
_next = answerId => {
let quiztaker = this.props.quiz.quiztakers_set[0].id;
let answer = this.state.selectedOption;
this.props.sendResponse(quiztaker, 1, 1);
let currentStep = this.state.currentStep;
let arrayLength = this.props.quiz.questions_count;
currentStep =
currentStep >= arrayLength - 1 ? arrayLength - 1 : currentStep + 1;
this.setState({
currentStep,
selectedOption: null
});
};
_prev = () => {
let currentStep = this.state.currentStep;
currentStep = currentStep <= 0 ? 0 : currentStep - 1;
this.setState({
currentStep
});
};
componentWillMount() {
this.props.getQuiz(this.props.match.params.slug);
}
render() {
if (!this.props.quiz) {
return <h1>LOADING...</h1>;
}
let icon_next =
this.state.currentStep === this.props.quiz.questions_count - 1
? "fas fa-check"
: "fas fa-angle-right";
let icon_prev =
this.state.currentStep === 0 ? "d-none" : "dir_control left";
return (
<Fragment>
<Navbar />
<div className="row question">
<div className="card col-lg-8 col-md-8 mx-auto">
{this.props.quiz.question_set.map((question, index) => {
let { currentStep } = this.state;
let style = {};
if (currentStep === index) {
() => this._setQuestion(question.id);
style = {
display: "inline-block"
};
} else {
style = {
display: "none"
};
}
return (
<div
className="card-body"
style={style}
key={question.id}
id={index}
>
<form onSubmit={this.onSubmit}>
<h5 className="card-title">{question.label}</h5>
{question.answer_set.map(answer => {
return (
<div className="answers" key={answer.id}>
<input
type="radio"
name={answer.question}
id={answer.id}
value={answer.text}
checked={this.state.selectedOption === answer.id}
onChange={this.handleOptionChange}
/>
<label htmlFor={answer.id}>{answer.text}</label>
<button
type="submit"
onClick={this._prev}
className={icon_prev}
>
<span className="fas fa-angle-left"></span>
</button>
<button
type="submit"
onClick={this._next}
className="dir_control right"
>
<span className={icon_next}></span>
</button>
</div>
);
})}
</form>
</div>
);
})}
</div>
</div>
</Fragment>
);
}
}
const mapStateToProps = state => ({
user: state.auth.user,
quiz: state.quizzes.quiz.quiz
});
export default connect(
mapStateToProps,
{ getQuiz, sendResponse }
)(QuizDetail);
每当我尝试不使用任何参数时,它都可以正常工作,但是当我添加参数时,它根本不起作用。
使用react网站上的文档无济于事。我已经尽一切努力使这项工作。我也尝试了堆栈溢出很长时间,直到我决定自己问这个问题。
P / S:我使用的是基于类的组件,而不是功能组件
答案 0 :(得分:0)
之所以发生递归,是因为您总是在setState
中调用map
,并且如果questionId
相同,则不要告诉组件忽略重新渲染
shouldComponentUpdate(nextProps, nextState) {
return this.state.questionId !== nextState.questionId;
}
或者,您可以在map
回调中添加此保护
let { currentStep, questionId } = this.state;
if (currentStep === index && questionId !== question.id) {
this._setQuestion(question.id);
...
}
事实上,说了这是不管用的,因为您在setState
期间不能调用render
。如果将其移至componentDidMount
/ componentDidUpdate
setQuestion() {
const questionId = this.props.quiz.question_sets[this.state.currentStep];
this.setState({ questionId });
}
componentDidMount() {
setQuestion();
}
componentDidUpdate() {
setQuestion();
}