我正在尝试使用react创建元素列表,并在单击单个元素时更新此列表的父级状态。
整个容器是App.jsx(祖父母)
notifyDataSetChanged()
父容器是Results.jsx
class App extends Component {
constructor(props) {
super(props);
this.state = {
selectedClass: null,
query: "cs 2110"
}
this.handleSelectClass.bind(this);
}
handleSelectClass(classId) {
console.log(classId);
//get the id of the course and get full course details
Meteor.call('getCourseById', classId, function(error, result) {
if (!error) {
console.log(this.state);
this.setState({selectedClass: result, query: ""}, function() {
console.log(this.state.selectedClass);
console.log(this.state.query);
});
} else {
console.log(error)
}
});
}
//check if a class is selected, and show a coursecard only when one is.
renderCourseCard() {
var toShow = <div />; //empty div
if (this.state.selectedClass != null) {
toShow = <CourseCard course={this.state.selectedClass}/>;
}
return toShow;
}
render() {
return (
<div className="container">
<header>
<h1>Todo List</h1>
</header>
<div className='row'>
<input />
<Results query={this.state.query} clickFunc={this.handleSelectClass}/>
</div>
<div className='row'>
<div className="col-md-6">
{this.renderCourseCard()}
</div>
<div className="col-md-6 panel-container fix-contain">
<Form courseId="jglf" />
</div>
</div>
</div>
);
}
}
和课程列表项是孙子组件
export class Results extends Component {
constructor(props) {
super(props);
}
renderCourses() {
if (this.props.query != "") {
return this.props.allCourses.map((course) => (
//create a new class "button" that will set the selected class to this class when it is clicked.
<Course key={course._id} info={course} handler={this.props.clickFunc}/>
));
} else {
return <div />;
}
}
render() {
return (
<ul>
{this.renderCourses()}
</ul>
);
}
}
我按照这里的建议Reactjs - How to pass values from child component to grand-parent component?来传递一个回调函数,但回调仍然无法识别祖父母的状态。即使classId正确,App.jsx中的console.log(this.state)也会返回undefined,并且错误显示“在传递调用'getCourseById'的结果时出现异常:TypeError:this.setState不是函数”
这是绑定问题吗?我已经尝试了这个,没有课程作为自己的组件,并有同样的问题。
答案 0 :(得分:0)
快速查看代码。我可以看到这个问题就在这里。即使你已经将你的函数限制在你的组件中,你也在使用一个meteor调用,它将结果范围限定在它自己的函数作用域中,这意味着它将无法访问this.setState。您可以使用胖箭头功能来解决此问题,但您需要确保使用ES6。
Meteor.call('getCourseById', classId, function(error, result) => {
if (!error) {
console.log(this.state);
this.setState({selectedClass: result, query: ""}, function() {
console.log(this.state.selectedClass);
console.log(this.state.query);
});
} else {
console.log(error)
}
});
以强>
Meteor.call('getCourseById', classId, (error, result) => {
if (!error) {
console.log(this.state);
this.setState({selectedClass: result, query: ""}, () => {
console.log(this.state.selectedClass);
console.log(this.state.query);
});
} else {
console.log(error)
}
});
您还错误地将您的功能绑定到您的组件。
this.handleClassSubmit = this.handleClassSubmit.bind(this);