我知道這是反應中最常見的問題之一:「爲什麼狀態沒有正確更新我的組件?」而且我搜索了很多東西,但是似乎無法解決這個問題。ReactJs不更新嵌套組件
這個問題最常見的答案是我在某處變異狀態,但我無法發現它。
我試圖創建一個標籤,其中還可以動態地添加表單字段按這篇文章,我發現了一個表格:https://goshakkk.name/array-form-inputs/
一切工作正常,除了當我刪除一個動態添加表格,該表格數組的值不會根據狀態進行更新。
我的代碼如下:
import React, { Component } from 'react';
import EditorFooter from '../../editor/moduleEditor/Footer';
import EditorHeader from '../../editor/moduleEditor/Header';
class Tab extends Component {
render() {
const currentTabNumber = this.props.currentTabNumber;
const cssClass = currentTabNumber === this.props.number ? 'active' : '';
return (
<button className={`tab ${cssClass}`} onClick={(e) => this.props.switchTab(this.props.number)}>{this.props.name}</button>
)
};
};
class CourseForm extends Component {
render() {
const index = this.props.index;
return (
<div className="inner-form">
<h3>Kurs {index}</h3>
<button className="removeForm" onClick={this.props.handleRemoveCourse(index)}>Remove form</button>
<h4>Kursens namn</h4>
<input type="text" name="name" defaultValue={this.props.course.name} onChange={this.props.handleInputChange(index)} />
<h4>Årtal</h4>
<p className="helper-text">Exempel: 2002-2003</p>
<input type="text" name="years" defaultValue={this.props.course.years} onChange={this.props.handleInputChange(index)} />
</div>
)
};
};
class Editable extends Component {
constructor(props) {
super(props);
this.state = {
showTab: 1,
};
}
switchTab = (tabNr) => {
this.setState({ showTab: tabNr });
}
render() {
const courses = this.props.courses;
const coursesList = courses.map((course, index) =>
<CourseForm key={index} index={index} course={course} handleInputChange={this.props.handleCourseChange} handleRemoveCourse={this.props.handleRemoveCourse} />
);
return (
<div id={`${this.props.moduleItem.ModuleId}_Editor`} className="form notransition">
<EditorHeader templateName="Simple test form" />
<section className="form-inner">
<div className="tabs">
<Tab switchTab={this.switchTab} currentTabNumber={this.state.showTab} number={1} name="Information" />
<Tab switchTab={this.switchTab} currentTabNumber={this.state.showTab} number={5} name="Kurser" />
</div>
{this.state.showTab === 1 ?
<div className="tab-block">
<h4>Bild</h4>
<p className="helper-text">Tänk på att cv-bilden ska vara av bra kvalitet. Låt gärna en fotograf komma och fota hela projektgruppen.</p>
<input type="file" name="image" defaultValue={this.props.image} onChange={this.props.handleInputChange} />
<h4>Slogan</h4>
<p className="helper-text">Om du skulle skriva en kort reklamslogan om dig själv, vad skulle det vara?</p>
<textarea name="slogan" defaultValue={this.props.slogan} onChange={this.props.handleInputChange}></textarea>
</div>
:
null
}
{this.state.showTab === 5 ?
<div className="tab-block">
{coursesList}
<button className="addForm" onClick={this.props.handleAddCourse}>Add form</button>
</div>
:
null
}
</section>
<EditorFooter {...this.props} submitForm={this.props.saveForm} />
</div>
);
}
};
class Readable extends Component {
render() {
const props = this.props;
return (
<section className="module align-top notransition">
</section>
);
}
};
class Template extends Component {
render() {
const props = this.props;
return (
<section className="module align-top">
</section>
);
}
};
class SimpleTestForm extends Component {
constructor(props) {
super(props);
this.state = {
slogan: "",
image: "",
courses: [{ name: '', years: '' }],
};
}
onAddCourseForm = (event) => {
this.setState({
courses: this.state.educations.concat([{ name: '', years: '' }])
});
}
handleCourseChange = (index) => (e) => {
const newCourses = this.state.courses.map((course, newIndex) => {
if (index !== newIndex) return course;
const target = e.target;
const value = target.type === 'checkbox' ? target.checked : target.value;
const name = target.name;
return { ...course, [name]: value };
});
this.setState({ courses: newCourses });
}
handleRemoveCourse = (index) => (e) => {
this.setState({
courses: this.state.courses.filter((courses, newIndex) => index !== newIndex)
});
//this.setState(this.state);
}
handleAddCourse =() => {
this.setState({
courses: this.state.courses.concat([{ name: '', years: '' }])
});
}
saveForm = (e) => {
console.log(this.state);
}
handleInputChange = (e) => {
const target = e.target;
const value = target.type === 'checkbox' ? target.checked : target.value;
const name = target.name;
this.setState({
[name]: value
});
}
render() {
const inEditMode = this.props.mode === 'edit';
const inTemplateMode = this.props.mode === 'template';
const inReadMode = this.props.mode === 'read';
return (
<div>
{inEditMode ?
<Editable {...this.props}
handleInputChange={this.handleInputChange}
onChangeEditor={this.onChangeEditor}
saveForm={this.saveForm}
handleCourseChange={this.handleCourseChange}
handleAddCourse={this.handleAddCourse}
handleRemoveCourse={this.handleRemoveCourse}
courses={this.state.courses}
slogan={this.state.slogan}
image={this.state.image}
/>
:
null
}
{inReadMode ?
<Readable {...this.props}
/>
:
null
}
{inTemplateMode ?
<Template {...this.props}
/>
:
null
}
</div>
);
}
};
module.exports = SimpleTestForm;
我知道這是一個有點長,我已經試過熬下來。
我的麻煩是,如果我在「Kruser」選項卡下添加三個表單,然後填充它們,然後刪除中間的一個,刪除正確的表單(我可以看到如果我登錄狀態),但它的數據來自下面的表格。直到我切換標籤並返回到Kurser選項卡,它才顯示正確的數據。
謝謝!這工作,但有一個例外...我創建數組項時不得不放置'generate()',而不是當我映射數組''課程:this.state.courses.concat([{name:' ',年:',itemKey:generate()}])' – Winter
如果你更新答案,那麼我會接受它。並感謝ternarys上的提示! :) – Winter
更新了答案,很高興它適合你,愉快的編碼。我想你也把它添加到初始狀態,但我想它是自我解釋給其他讀者 – hyde