3

I am continuing to learn about the various frameworks we can use with SPFX.

I have stumbled upon a problem, which according to various websites out there it should work, so I'm sure the problem is a minor thing.

I would like to include another component within a render, the component is called 'DCTest' and i want to pass an attribute 'thisCount'.

With IntelliSense there appears to be an error with this line.

 <DCLabel thisCount={0}>Label12345</DCLabel>

specifically the thisCount part. I can read the 'this.props.children' text absolutely fine. It just seems to be this additional attribute that it doesn't like.

The error message is: property 'thisCount' does not exist on type 'IntrinsicAttributes & IntrinsicClassAttributes

I have included the code below, any help would be greatly appreciated.

  import * as React from 'react';
import { css } from 'office-ui-fabric-react';

import styles from '../ReactWebPart.module.scss';
import { IReactWebPartWebPartProps } from '../IReactWebPartWebPartProps';

export interface IReactWebPartProps extends IReactWebPartWebPartProps {

}



export default class ReactWebPart extends React.Component<IReactWebPartProps, {}>
{


  constructor(props)
  {
    super(props);

    this.state = { dcText2: props.dcText.toString(), testvar: "12434", count: 0 };



    //debugger;
  }

  public button_click(): void {
    // do something here

    console.log("dctest - on click ");

    this.setState({ dcText2: "setting state here", count: ++this.state["count"] });



    //this.forceUpdate();
  }

  public componentWillMount(): void
  {
    console.log("dctest - componenet will mount");

    //this.dcText2 = this.state.dcText;
  }

  public shouldComponentUpdate(nextProps: any, nextState: any): boolean
  {
    console.log("dctest - shouldComponenetUpdate [" + this.state["count"] + "]");
    console.log(nextProps);
    console.log(nextState);

    //this.setState({ dcText: "setting state here" });

    //return (this.state["count"] == 1);


    return true;

  }

  public componentDidUpdate(prevProps): void {

    console.log("dctest - componentDidUpdate " + Date.now().toString());
    console.log(prevProps);
  }



  public render(): JSX.Element
  {

    console.log("dctest - render :: " + Date.now().toString());

    return (
      <div className={styles.reactWebPart}>
        <div className={styles.container} >
          <div className={css('ms-Grid-row ms-bgColor-themeDark ms-fontColor-white', styles.row)}>
            <div className='ms-Grid-col ms-u-lg10 ms-u-xl8 ms-u-xlPush2 ms-u-lgPush1'>
              <span className='ms-font-xl ms-fontColor-white'>
                Welcome to SharePoint!
              </span>
              <p className='ms-font-l ms-fontColor-white'>
                Customize SharePoint experiences using Web Parts.
              </p>

              <p className='ms-font-l ms-fontColor-white'>
                dcTest :: { this.state["dcText2"] }
              </p>

            <button onClick={ () => this.button_click() } >Click here</button>

              <a
                className={css('ms-Button', styles.button)}
                href='https://github.com/SharePoint/sp-dev-docs/wiki'
              >
                <span className='ms-Button-label' >Learn more</span>
              </a>





                 <DCLabel thisCount={0}>Label12345</DCLabel>

            </div>
          </div>
        </div>
      </div>
    );
  }
}

const DCLabel = React.createClass({

  // count: React.PropTypes.number,

  // propTypes:
  // {
  //   count: React.PropTypes.number.isRequired
  // }

  // ,

  render()
  {
    console.log("label is rendering!");


    console.log("label count!" + this.props.Count);

    // return React.createElement("label", {className: "label"},
    //   React.createElement("span", {className: "label"}, this.props.label), this.label_text);


    //console.log("test -- " + this.props.test);

    return (
      <label className="label" thisCount={ () => this.props.thisCount } >
        {this.label_text} || { this.props.thisCount }
      </label>
    );
  }
,

  shouldComponentUpdate: function(nextProps, nextState): boolean
  {

    console.log("label should update?? " +  (this.props.children == "Label12345"));

    //return (this.props.children == "Label12345");

    return true;
  }


});
5

So, you're using React as your JavaScript framework, if you don't have a lot of experience with React and how it works I'd suggest you to first read more about it and play with it outside the new SharePoint framework, that will ensure that you understand the basic concepts without being overwhelmed with all the technologies in the new framework.

In your case you can create a simple Stateless React component. You can think of a stateless component as a simple function that takes properties as the input parameter and returns html. The link below shows how you could implement it.

http://pastebin.com/gGTC6ANx

Also although Typescript is a superset of JavaScript and you can create your React components like you did with React.createClass, I'd recommend sticking with the Typescript syntax.

For example to create a stateful React component you could do

export default class YouReactComponent extends React.Component<YourComponentPropsInterface, YourComponentStateInterface> {
//impementation goes in here
}

Note that React.Component is generic and the first typed parameter is interface that defines the properties of your component and second defines the state.

Hope that helps..

  • Hi, Rafael thanks for your post. I will definitely take some of your points on board. But something I would still like to know is how to make components communicate to each other, say for example, in my original post - passing an attribute into a component from another component. I have seen on the internet it is possible and tried implementing something similar to how I have attempted in the above, just wondering what i would need to do to pass an attribute in a similar way to what I have been doing. Many Thanks, – devlin Aug 31 '16 at 7:32
  • Hi @devlin, check out this: Communicate Between Components When you're passing properties you do so by passing an attribute to your control. If you want to pass a propery of the parent down to the child you could do <DCLabel thisCount={this.props.ParentProperty}>Label12345</DCLabel> If you want to pass a property that is a state of your parent you could do <DCLabel thisCount={this.state.count}>Label12345</DCLabel> Hope that clarifies a bit. – Rafael Rocha Aug 31 '16 at 15:04

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.