![](/img/trans.png)
[英]How do I pass props to get a cancel button to work in React on a Redux-Form
[英]How to pass down props to decorated form in `redux-form`?
我正在使用redux-form
構建向導表單,並遇到一個問題,其中onClick
處理程序沒有作為prop從容器組件傳遞到表單中。
我已經搜索了過去幾個小時的文檔,但無濟於事……似乎有一種方法可以將道具傳遞到裝飾好的HOC中,但是我看不到任何此類示例。
以下是相關代碼:
RadioButtons.js
(在其中調用onClick函數)
const RadioButtons = props => {
const { question, handleClick } = props;
const radioClassNames = classNames({
"radio-button": true,
"radio-button-image-wrapper": question.image,
"radio-button-text-wrapper": !question.image,
});
return (
<div className="radio-buttons">
<div className="radio-buttons-wrapper">
{question.options.map((option, index) => (
<div className={radioClassNames} key={index} onClick={handleClick}>
<Field
component="input"
type="radio"
name={`option-${option}`}
id={`option-${option}`}
/>
<label className="radio-button-text" htmlFor={option}>
{option}
</label>
)}
</div>
)
)}
</div>
</div>
)
}
RadioButtons.PropTypes = {
question: PropTypes.object.isRequired,
handleClick: PropTypes.func,
}
export default RadioButtons;
當我在React DevTools中檢查這個組件時,它沒有這個道具。 以下組件中也沒有...
Question.js
(確定要呈現的問題類型;滑塊,單選按鈕,文本/電子郵件/電話輸入等)
const Question = props => {
const { handleSubmit, onBlur, question, handleClick } = props;
return (
<div className={`question question-${question.name}`}>
<form className={props.className} onSubmit={handleSubmit}>
<div className="question-wrapper">
<label className={`question-label-${question.name}`}>{question.text}</label>
{ question.image === true && question.type !== "checkbox" && question.type !== "radio" &&
<img className="question-image" src={`/images/${question.name}.png`} />
}
{ question.type === "radio" && <RadioButtons question={question} handleClick={handleClick} /> }
{ question.type === "range" && <Slider question={question} /> }
{ question.type !== "checkbox" && question.type !== "radio" && question.type !== "range" &&
<Field
component={question.component}
type={question.type}
name={question.name}
placeholder={question.placeholder}
onBlur={onBlur}
/>
}
</div>
</form>
</div>
)
}
Question.PropTypes = {
handleSubmit: PropTypes.func,
onBlur: PropTypes.func,
question: PropTypes.object.isRequired,
handleClick: PropTypes.func,
}
export default reduxForm({
form: 'quiz',
destroyOnUnmount: false,
forceUnregisterOnUnmount: true,
})(Question);
QuestionContainer.js
(包裝器Question.js
;確定是否呈現在屏幕上或只是一個在多個問題)。 handleClick
道具終於出現在這里!
const QuestionContainer = props => {
const { question, handleClick } = props;
const questionClassNames = classNames({
'question-wrapper': true,
'question-single': props.question !== 'combined',
'question-multiple': props.question === 'combined',
});
const renderQuestions = question => {
if (question.component === 'combined') {
return (
<div className="multi-question-container">
<label className="multi-question-label">{question.text}</label>
<div className="multi-question-wrapper">
{question.subQuestions.map((subQuestion, index) => {
const newName = `${question.name}-${subQuestion.name}`;
const newSubQuestion = Object.assign({}, subQuestion, { name: newName })
return (
<Question
question={newSubQuestion}
key={index}
className={questionClassNames}
handleClick={handleClick}
/>
)
})}
</div>
</div>
)} else {
return (
<Question
question={question}
className={questionClassNames}
/>
)
}
}
return (
<div className="question-container">
{renderQuestions(question)}
</div>
)
}
QuestionContainer.PropTypes = {
question: PropTypes.object.isRequired,
handleClick: PropTypes.func,
}
export default QuestionContainer;
但是然后... handleClick
道具沒有顯示在Quiz
組件中,我實際上需要使用它來調用nextScreen()
:
class Quiz extends Component {
constructor(props) {
super(props);
this.state = {
screen: 0
}
}
nextScreen = () => {
console.log("nextScreen");
if (this.state.screen < data.questions.length) {
this.setState({screen: this.state.screen + 1});
} else {
this.props.calculateResult(this.props.form.quiz.values);
this.props.history.push('/congratulations');
}
}
lastScreen = () => {
if (this.state.screen > 1) {
this.setState({screen: this.state.screen - 1});
} else {
this.props.history.push('/');
}
}
render() {
const currentQuestion = Object.assign({}, data.questions[this.state.screen]);
let arrowSource = `/images/arrow-button-${arrowColor}.png`;
return (
<div>
<div className="quiz-wrapper">
<ArrowButton src={arrowSource} route="back" handleClick={this.lastScreen} />
<div className="quiz-wrapper-inner">
<QuestionContainer question={currentQuestion} handleClick={this.nextScreen} />
</div>
<ArrowButton src={arrowSource} route="forward" handleClick={this.nextScreen} />
</div>
</div>
)
}
}
const mapStateToProps = state => {
return {
form: state.form,
}
};
const mapDispatchToProps = dispatch => {
return {
calculateResult: answers => dispatch(calculateResult(answers)),
}
};
export default connect(mapStateToProps, mapDispatchToProps)(Quiz);
ArrowButton
組件上的handleClick
道具工作正常,可以nextScreen()
調用nextScreen()
/ lastScreen()
。 它只是在QuestionContainer
中沒有傳遞下來。
你有兩個實例Questions
組件的QuestionsContainer
組件。 滿足question.component === 'combined'
條件時,您正在傳遞handleClick
道具,但沒有通過,因此在您的Questions
組件中不可用。
您還需要在else條件下傳遞handleClick作為道具
const renderQuestions = question => {
if (question.component === 'combined') {
return (
<div className="multi-question-container">
<label className="multi-question-label">{question.text}</label>
<div className="multi-question-wrapper">
{question.subQuestions.map((subQuestion, index) => {
const newName = `${question.name}-${subQuestion.name}`;
const newSubQuestion = Object.assign({}, subQuestion, { name: newName })
return (
<Question
question={newSubQuestion}
key={index}
className={questionClassNames}
handleClick={handleClick}
/>
)
})}
</div>
</div>
)} else {
return (
<Question
question={question}
className={questionClassNames}
handleClick={handleClick}
/>
)
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.