Reputation: 4502
I would like to set state of parent component from child component. I tried using props however its giving error Uncaught TypeError: this.props.setTopicClicked is not a function
. And is there more efficient way for setting state of parent component instead of using props? I would like to set state of isTopicClicked: true
main-controller.jsx
import {React, ReactDOM} from '../../../build/react';
import SelectedTopicPage from '../selected-topic-page.jsx';
import TopicsList from '../topic-list.jsx';
import topicPageData from '../../content/json/topic-page-data.js';
export default class MainController extends React.Component {
state = {
isTopicClicked: false,
topicPageData
};
onClick(topicID) {
this.setState({
isTopicClicked: true,
topicsID: topicID
});
};
setTopicClicked(event){
this.setState({isTopicClicked: event});
};
render() {
return (
<div className="row">
{this.state.isTopicClicked
? <SelectedTopicPage topicsID={this.state.topicsID} key={this.state.topicsID} topicPageData={topicPageData}/>
: <TopicsList onClick={ this.onClick.bind(this) }/>}
</div>
);
}
};
selected-topic-page.jsx
import {React, ReactDOM} from '../../build/react';
import SelectedTopicPageMarkup from './selected-topic-page-markup.jsx';
import NextPrevBtn from './next-prev-btn.jsx';
export default class SelectedTopicPage extends React.Component {
state = {
topicPageNo: 0,
total_selected_topic_pages: 1
};
navigateBack(topicPageNo) {
if (this.state.topicPageNo > 0){
topicPageNo = this.state.topicPageNo - 1;
}
else {
topicPageNo = 0;
}
this.setState({topicPageNo : topicPageNo});
};
navigateNext(totalPagesInSelectedTopic) {
let topicPageNo;
if (totalPagesInSelectedTopic > this.state.topicPageNo + 1){
topicPageNo = this.state.topicPageNo + 1;
}
else if (totalPagesInSelectedTopic == this.state.topicPageNo + 1) {
this.props.setTopicClicked(true);
}
else {
topicPageNo = this.state.topicPageNo;
}
this.setState({topicPageNo : topicPageNo});
};
render() {
let topicsID = this.props.topicsID;
let topicPageNo = this.state.topicPageNo;
return (
<div>
{this.props.topicPageData.filter(function(topicPage) {
// if condition is true, item is not filtered out
return topicPage.topic_no === topicsID;
}).map(function (topicPage) {
let totalPagesInSelectedTopic = topicPage.topic_pages.length;
return (
<div>
<div>
<SelectedTopicPageMarkup headline={topicPage.topic_pages[0].headline} key={topicPage.topic_no}>
{topicPage.topic_pages[topicPageNo].description}
</SelectedTopicPageMarkup>
</div>
<div>
<NextPrevBtn moveNext={this.navigateNext.bind(this, totalPagesInSelectedTopic)} key={topicPage.topic_no} moveBack={this.navigateBack.bind(this, topicPageNo)}/>
</div>
</div>
);
}.bind(this))}
</div>
);
};
};
Upvotes: 0
Views: 605
Reputation: 816262
It seems you forgot to pass setTopicClicked
to the child:
setTopicClicked={this.setTopicClicked.bind(this)}
Upvotes: 3
Reputation: 1309
Your <SelectedTopicPage />
does not contain setTopicClicked
as props
which results into the error
<SelectedTopicPage
topicsID={this.state.topicsID}
key={this.state.topicsID}
topicPageData={topicPageData}/>
You can try using a flux
implementation to handle the state of your application and just pass props
to the component. Otherwise, I think you're stuck in passing in setting the state using the component or its children.
Upvotes: 0