简体   繁体   中英

How to setState from child component in React

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>
        );
    };
};

看来您忘记了将setTopicClicked传递给孩子:

setTopicClicked={this.setTopicClicked.bind(this)}

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM