Мой список опций (доменов), основанных на выбранном курсе, обновляется в родительском состоянии, но ребенок не будет обновлять / наследовать реквизиты, отправленные с ним. Ребенок должен получить состояние доменов от родителя и составить из него список опций. Он работает при инициализации, но не будет обновляться после изменения курса в родительском компоненте.
AddQuestion.js
class AddQuestion extends Component {
constructor(props){
super(props)
// initiate all states
this.state = {
course: '',
domains: []
}
}
render() {
return (
<MainQuestion formError={this.state.formError} levels={this.state.levels} years={this.state.years} courses={this.state.courses} introductionlist={this.state.introductionlist} subQuestions={this.state.subQuestions} numSubQuestion={this.state.numSubQuestion} handleCourseChange={this.handleCourseChange} postQuestion={this.postQuestion} addSubQuestion={this.addSubQuestion} formHasError={this.state.formHasError} validateForm={this.validateForm}/>
);
}
// handle onchange course input
handleCourseChange = (e) => {
this.setState({
course: e.target.value
},
function(e) {
console.log(this.state.course);
this.getResponseDomains();
},
this.validateForm(e)
);
}
// get domains based on course
getResponseDomains = () => {
console.log(this.state.course);
// fetch data from backend
axios.get('/api/domain/get?course=' + this.state.course, {
course: this.state.course
})
.then(response => response.data.data)
.then((json) => {
json.map(obj => this.setState({domains: Object.values(obj) }));
this.state.domains = json;
// map a option input for each fetched domain
let domainslist = Object.keys(this.state.domains).map(key =>
<option label={this.state.domains[key].name} value={this.state.domains[key].id} />
)
this.setState({
domains: domainslist
});
})
.catch((error) => {
console.log(error);
});
}
// Add the input field to a new subquestion
addSubQuestion = () => {
this.setState({
numSubQuestion: this.state.numSubQuestion + 1,
formHasError: true
});
//reset array
subQuestions = [];
let errormessages = '';
let errornum = this.state.numSubQuestion + 1;
//fill array for amount of subquestions needed
for (var i = 0; i <= this.state.numSubQuestion; i += 1) {
subQuestions.push(<SubQuestion key={i} number={i + 1} domain={this.state.domain} course={this.state.course} domains={this.state.domains} subjects={this.state.subjects} />);
this.setState({
subQuestions: subQuestions,
formError: errormessages
});
}
MainQuestion.js
// This is the main question (e.d. level, year, course and introduction)
class MainQuestion extends Component {
constructor(props){
super(props)
}
render() {
return (
<div className="addQuestion-wrapper">
<div className="logo mx-auto">
<img src="/img/logo-white.png"/>
</div>
<section className="addQuestion container">
<form id="addQuestionForm">
<p className="text-danger">{ this.props.formError }</p> {/* display errors */}
<div className="row d-flex prequestion">
<div className="col-12 mb-3">
<h2>Nieuwe vraag toevoegen</h2>
</div>
<div ref="error3" className="input-group col-12 col-lg-6" id="levels-wrapper">
<div>
<p className="label">Niveau</p>
{this.props.levels} {/* display fetched levels */}
</div>
</div>
<div ref="error4" className="input-group col-12 col-lg-6" id="years-wrapper">
<div>
<p className="label">Leerjaar</p>
{this.props.years} {/* display fetched years */}
</div>
</div>
<div ref="error5" className="input-group col-12 col-lg-6">
<p className="label">Vak</p>
<select onChange={this.props.handleCourseChange} name="course" id="select-courses">
<option value="" disabled selected>--Kies een vak</option>
{this.props.courses} {/* display fetched courses */}
</select>
</div>
<div ref="error10" className="input-group col-12 col-lg-12">
{this.props.introductionlist} {/* display created introduction textarea */}
</div>
</div>
{ this.props.subQuestions } {/* display amount of subquestions in the array */}
{/* add subquestion button */}
<div className="AddSubquestion">
<button className="btn" onClick={ this.props.addSubQuestion } disabled={this.props.formHasError}>Subvraag toevoegen</button>
</div>
{/* post question button */}
<div className="input-group" id="submit">
<button className="btn" onClick={ this.props.postQuestion } value="Aanmaken" disabled={this.props.formHasError}>Verzend</button>
</div>
</form>
</section>
</div>
);
}
}
export default AddQuestion;
SubQuestion.js
class SubQuestion extends Component {
constructor(props){
super(props)
// initiate all states
this.state = {
course: props.course,
domains: []
}
}
render() {
return (
<div className="row d-flex justify-content-center question mt-5">
<div className="col-12">
<h3> Subvraag {this.props.number} </h3> {/* display number of subquestion. Fetched from key of created child component */}
</div>
<div ref="error" className="input-group col-12 col-lg-6" id="type-wrapper">
{this.state.type} {/* display fetched type */}
</div>
<div ref="error2" className="input-group col-12 col-lg-6" id="questionings-wrapper">
<div>
<p className="label">Vraagstelling</p>
{this.state.questionings} {/* display fetched questionings */}
</div>
</div>
<div ref="error6" className="input-group col-12 col-lg-12">
{this.state.question} {/* display created textarea for questiona AND answer */}
</div>
<div ref="error7" className="input-group col-12 col-lg-6">
<p className="label">Domein</p>
<select id="select-domains" name={`domain-${this.props.number}`} onChange={this.handleDomainChange}>
<option value="" disabled selected>--Kies een domein</option>
{this.props.domains} {/* display fetched domains */}
</select>
</div>
<div ref="error8" className="input-group col-12 col-lg-6" id="select-subjects">
<p className="label">Onderwerp</p>
<select onChange={this.props.handleSubjectChange} name={`subject-${this.props.number}`}>
<option value="" disabled selected>--Kies een onderwerp</option>
{this.state.subjects} {/* display fetched subjects */}
</select>
</div>
<div ref="error9" className="input-group col-12 col-lg-12" id="time-points-rtti">
<div className="time mr-4">
{/* display time input */}
<p className="label">Tijdsduur</p>
<input type="number" name={`tijdsduur-${this.props.number}`} min="1" placeholder="tijd in minuten" onChange={this.props.handleTimeChange}/>
</div>
<div className="points mr-4">
{/* display points input */}
<p className="label">Punten</p>
<input type="number" name={`points-${this.props.number}`} min="1" placeholder="punten" onChange={this.props.handlePointsChange}/>
</div>
<div className="rtti">
{/* display rtti input */}
<p className="label">RTTI</p>
<input type="radio" name={`RTTI-${this.props.number}`} id={`R-${this.props.number}`} value="1" onChange={this.props.handleRttiChange}/><label htmlFor={`R-${this.props.number}`}>R</label>
<input type="radio" name={`RTTI-${this.props.number}`} id={`T1-${this.props.number}`} value="2" onChange={this.props.handleRttiChange}/><label htmlFor={`T1-${this.props.number}`}>T1</label>
<input type="radio" name={`RTTI-${this.props.number}`} id={`T2-${this.props.number}`} value="3" onChange={this.props.handleRttiChange}/><label htmlFor={`T2-${this.props.number}`}>T2</label>
<input type="radio" name={`RTTI-${this.props.number}`} id={`I-${this.props.number}`} value="4" onChange={this.props.handleRttiChange}/><label htmlFor={`I-${this.props.number}`}>I</label>
</div>
</div>
</div>
);
}
componentWillReceiveProps(nextProps) {
this.setState({course: nextProps.course, domains: nextProps.domains });
}
// handle onchange domain input
handleDomainChange = (e) => {
this.setState({
domain: e.target.value
},
this.getResponseSubjects, // change subjects based on selected domain
this.props.validateForm(e)
);
}
// get subjects based on domain
getResponseSubjects = () => {
// fetch data from backend
axios.get('/api/subject/get?domain=' + this.state.domain, {
domain: this.state.domain
})
.then(response => response.data.data)
.then((json) => {
json.map(obj => this.setState({subjects: Object.values(obj) }));
this.state.subjects = json;
// map a option input for each fetched subject
let subjectslist = Object.keys(this.state.subjects).map(key =>
<option label={this.state.subjects[key].name} value={this.state.subjects[key].id} />
)
this.setState({
subjects: subjectslist
}
);
})
.catch((error) => {
console.log(error);
});
}
export default SubQuestion;
Ожидаемым результатом будет дочерний компонент, изменяющий домены в зависимости от курса. Эти переменные изменяют родительский AddQuestion, но не переходят как дочерние элементы в дочерние.