SOLVED

Unable to pass data from React component to webpart ts file

Copper Contributor

I have been unable to pass data from a react component back to the webpart ts using a function passed into props. I created the simplest example of this and continue to get the following error:

TypeError: Cannot read property 'props' of undefined

 

Here is my webpart files

 

ISync1Props.ts

 

export interface ISync1Props {
  descriptionstring;
  contextany;
  _dataSelectedany;
}
 
Sync1.tsx
 
import * as React from 'react';
import styles from './Sync1.module.scss';
import { ISync1Props } from './ISync1Props';
import { escape } from '@microsoft/sp-lodash-subset';

export default class Sync1 extends React.Component<ISync1Props,  {}> {

  constructor(propsISync1Props) {
    super(props);
  }


  public render(): React.ReactElement<ISync1Props> {
    return (
      <div className={ styles.sync1 }>
        <div className={ styles.container }>
          <div className={ styles.row }>
            <div className={ styles.column }>
              <span className={ styles.title }>Welcome to SharePoint!</span>
              <p className={ styles.subTitle }>Customize SharePoint experiences using Web Parts.</p>
              <p className={ styles.description }>{escape(this.props.description)}</p>
              <button onClick={this.passData}>Test</button>
            </div>
          </div>
        </div>
      </div>
    );
  }
  private passData() {
    var s = "My Data";
    console.log("passingData");
    this.props._dataSelected({ theData: s });
  }
}
 
Sync1WebPart.ts
 
import * as React from 'react';
import * as ReactDom from 'react-dom';
import { Version } from '@microsoft/sp-core-library';
import {
  IPropertyPaneConfiguration,
  PropertyPaneTextField
from '@microsoft/sp-property-pane';
import { BaseClientSideWebPart } from '@microsoft/sp-webpart-base';

import * as strings from 'Sync1WebPartStrings';
import Sync1 from './components/Sync1';
import { ISync1Props } from './components/ISync1Props';

export interface ISync1WebPartProps {
  descriptionstring;
}

export interface ISelectedData {
  theDatastring;
}

export default class Sync1WebPart extends BaseClientSideWebPart<ISync1WebPartProps> {


  private _selectedDataISelectedData;

  private _dataSelect = (dataISelectedData:( void => {
    this._selectedData = data;
    console.log("selectdData:"this._selectedData);
  }


  public render(): void {
    const elementReact.ReactElement<ISync1Props> = React.createElement(
      Sync1,
      {
        description: this.properties.description,
        context: this.context,
        _dataSelected: this._dataSelect      
      }
    );

    ReactDom.render(elementthis.domElement);
  }

  protected onDispose(): void {
    ReactDom.unmountComponentAtNode(this.domElement);
  }


  protected getPropertyPaneConfiguration(): IPropertyPaneConfiguration {
    return {
      pages: [
        {
          header: {
            description: strings.PropertyPaneDescription
          },
          groups: [
            {
              groupName: strings.BasicGroupName,
              groupFields: [
                PropertyPaneTextField('description', {
                  label: strings.DescriptionFieldLabel
                })
              ]
            }
          ]
        }
      ]
    };
  }
}
 
 
1 Reply
best response confirmed by jay chadwell (Copper Contributor)
Solution

@jay chadwell 

 

Ok solved it by looking at this article:

https://www.voitanos.io/blog/deal-with-undefined-this-react-event-handler-performant-way/

 

added  a bind statement in the constructor of the react component so that the passData function has proper reference to "this".

 

  constructor(propsISync1Props) {
    super(props);
    this.passData = this.passData.bind(this);

  }
1 best response

Accepted Solutions
best response confirmed by jay chadwell (Copper Contributor)
Solution

@jay chadwell 

 

Ok solved it by looking at this article:

https://www.voitanos.io/blog/deal-with-undefined-this-react-event-handler-performant-way/

 

added  a bind statement in the constructor of the react component so that the passData function has proper reference to "this".

 

  constructor(propsISync1Props) {
    super(props);
    this.passData = this.passData.bind(this);

  }

View solution in original post