React JS - Uncaught TypeError: Cannot read property 'bind' of undefined

12,369

You have several mistakes

  1. You should pass onClick to TopicsList

    render() {
      return (
        <div className="row">
          {this.state.isTopicClicked
            ? <SelectedTopicPage 
                 topicsID={this.state.topicsID} 
                 key={this.state.topicsID} 
                 topicPages={topicPages} />
            : <TopicsList onClick={ this.onClick.bind(this) } />}
        </div>
      );
    }
    
  2. remove onClick method from TopicsList

     onClick() {
       // ...
     },
    
  3. pass onClick callback from props

    <SingleTopicBox topicID="1" onClick={this.props.onClick} label="Topic"/>
    
  4. add to SingleTopicBox onClick event

    <div 
       className="single-topic" 
       data-topic-id={this.props.topicID} 
       onClick={ () => this.props.onClick(this.props.topicID) }
    >
      {this.props.label} {this.props.topicID}
    </div>
    
  5. you don't need call setState twice

     onClick(topicID) {
       this.setState({
         isTopicClicked: true, 
         topicsID: topicID
       });
     }
    

Example

Share:
12,369
Rahul Dagli
Author by

Rahul Dagli

Updated on June 30, 2022

Comments

  • Rahul Dagli
    Rahul Dagli almost 2 years

    I would like to show TopicsListcomponent when user clicks on SingleTopicBox component and hide SelectedTopicPage component. However, i'm getting error: Uncaught TypeError: Cannot read property 'bind' of undefined on topic-list.jsx file.

    main-controller.jsx

    import {React, ReactDOM} from '../../../build/react';
    
    import TopicsList from '../topic-list.jsx';
    import SelectedTopicPage from '../selected-topic-page.jsx';
    import topicPages from '../../content/json/topic-pages.js';
    
    export default class MainController extends React.Component {
    
      state = {
        isTopicClicked: false,
        topicPages
      };
    
      onClick(topicID) {
        this.setState({isTopicClicked: true});
        this.setState({topicsID: topicID});
      };
    
      render() {
        return (
          <div className="row">
            {this.state.isTopicClicked
              ? <SelectedTopicPage topicsID={this.state.topicsID} key={this.state.topicsID} topicPages={topicPages}/>
              : <TopicsList/>}
          </div>
        );
      }
    };
    

    topic-list.jsx

    import {React, ReactDOM} from '../../build/react';
    
    import SingleTopicBox from './single-topic-box.jsx';
    import SelectedTopicPage from './selected-topic-page.jsx';
    import topicPages from '../content/json/topic-pages.js';
    
    export default class TopicsList extends React.Component {
      onClick(){
        this.props.onClick.bind(null, this.topicID);
      },
      render() {
        return (
          <div className="row topic-list">
            <SingleTopicBox topicID="1" onClick={this.onClick} label="Topic"/>
            <SingleTopicBox topicID="2" onClick={this.onClick} label="Topic"/>
            <SingleTopicBox topicID="3" onClick={this.onClick} label="Topic"/>
            <SingleTopicBox topicID="4" onClick={this.onClick} label="Topic"/>
          </div>
        );
      }
    };
    

    single-topic-box.jsx

    import {React, ReactDOM} from '../../build/react';
    
    export default class SingleTopicBox extends React.Component {
    
        render() {
            return (
                <div>
                    <div className="col-sm-2">
                        <div className="single-topic" data-topic-id={this.props.topicID}>
                            {this.props.label} {this.props.topicID}
                        </div>
                    </div>
                </div>
            );
        }
    };