2017-06-27 74 views
0

我正在構建一個嚮導窗體,其中redux-form遇到問題,其中onClick處理程序未作爲從容器組件傳遞到窗體的道具傳遞。如何將道具傳遞給`redux-form`中的裝飾形式?

我搜索了過去幾個小時的文檔無濟於事......似乎可能有辦法將道具傳遞到裝飾的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; 

當我檢查在陣營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;確定是否在屏幕上顯示多個問題或僅顯示一個問題)。​​道具終於出現在這裏!

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; 

但後來......的​​道具不顯示在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組件工作正常,撥打nextScreen()/lastScreen()順利。只有在QuestionContainer中它不會被傳遞。

+1

當我看到你在向下傳遞的一個實例,而不是在其他的,所以,如果question.component不合並其沒有通過,那是什麼時候它將不可用在eQuestion組件中,參見'<問題 question = {question} className = {questionClassNames} />' –

+0

當然!不敢相信我沒有看到這個。接得好。 – Alacritas

回答

2

您在QuestionsContainer組件中有兩個Questions組件實例。當滿足question.component === 'combined'條件時,您通過​​支柱,但是不是,因此在您的Questions組件中不可用。

您需要通過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} 
     /> 
     ) 
    } 
    } 
相關問題