2017-06-27 6 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; 

、この支柱を有していません。ラッパー

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(;また、それは、(など、スライダー、ラジオボタン、テキスト/メール/ TEL入力、これはレンダリングするために、質問の種類を決定する)

Question.js ...次のコンポーネントでありますQuestion.jsの場合は、複数の質問を画面に表示するのか、それとも1つだけ表示するのかを決定します)。​​小道具は最終的にここに現れます!

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; 

しかし、その後...​​小道具nextScreen()呼び出すために、私は実際にそれを使用する必要がQuizコンポーネントでを、表示されません。

​​
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

他の条件で小道具としてhandleClickを渡す必要があり、そうquestion.componentが組み合わされていない場合は、そのそれは<質問 質問= {問題} クラス名= {} questionClassNames />もちろん、 '' –

+0

参照してください、目eQuestionコンポーネントで使用することはできませんときのthats渡しません!私はこれを見ていないとは信じられない。良いキャッチ。 – Alacritas

答えて

2

あなたはQuestionsContainerコンポーネントでQuestionsコンポーネントのインスタンスを2つ持っています。 question.component === 'combined'条件が満たされたとき、あなたは​​小道具を渡しているが、ないそうを、したがって、それはあなたのQuestionsコンポーネントでは使用できません。

あなたは私はあなたがしていない他の内の1つのインスタンスでそれを下に渡して見たようにも

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} 
     /> 
     ) 
    } 
    } 
関連する問題